@mixio-pro/kalaasetu-mcp 1.0.10 → 1.0.12

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mixio-pro/kalaasetu-mcp",
3
- "version": "1.0.10",
3
+ "version": "1.0.12",
4
4
  "description": "A powerful Model Context Protocol server providing AI tools for content generation and analysis",
5
5
  "type": "module",
6
6
  "module": "src/index.ts",
@@ -8,6 +8,7 @@ export function getStorage(): StorageProvider {
8
8
  if (!storageInstance) {
9
9
  const type = process.env.STORAGE_PROVIDER || "local";
10
10
  console.error(`Initializing storage provider: ${type}`);
11
+ console.error(`Base path (cwd): ${process.cwd()}`);
11
12
 
12
13
  if (type === "gcs") {
13
14
  const bucket = process.env.GCS_BUCKET;
@@ -40,7 +40,12 @@ export class LocalStorageProvider implements StorageProvider {
40
40
  if (!path.isAbsolute(filePath)) {
41
41
  fullPath = path.resolve(this.basePath, filePath);
42
42
  }
43
- return fs.existsSync(fullPath);
43
+ try {
44
+ await fs.promises.access(fullPath, fs.constants.F_OK);
45
+ return true;
46
+ } catch {
47
+ return false;
48
+ }
44
49
  }
45
50
 
46
51
  async getPublicUrl(filePath: string): Promise<string> {
@@ -18,9 +18,23 @@ const ai = new GoogleGenAI({
18
18
 
19
19
  async function fileToGenerativePart(filePath: string) {
20
20
  const storage = getStorage();
21
- if (!(await storage.exists(filePath))) {
22
- throw new Error(`File not found: ${filePath}`);
21
+
22
+ // Check if file exists
23
+ const exists = await storage.exists(filePath);
24
+ if (!exists) {
25
+ // Try to provide more helpful error information
26
+ const isAbsolute = path.isAbsolute(filePath);
27
+ const resolvedPath = isAbsolute
28
+ ? filePath
29
+ : path.resolve(process.cwd(), filePath);
30
+ throw new Error(
31
+ `File not found: ${filePath}\n` +
32
+ `Resolved path: ${resolvedPath}\n` +
33
+ `Is absolute: ${isAbsolute}\n` +
34
+ `CWD: ${process.cwd()}`
35
+ );
23
36
  }
37
+
24
38
  const imageBytes = await storage.readFile(filePath);
25
39
  return {
26
40
  inlineData: {
@@ -153,8 +167,19 @@ async function processVideoInput(
153
167
  } else {
154
168
  // Local file processing - use File Upload API
155
169
  const storage = getStorage();
156
- if (!(await storage.exists(input))) {
157
- throw new Error(`Video file not found: ${input}`);
170
+
171
+ // Check if file exists
172
+ const exists = await storage.exists(input);
173
+ if (!exists) {
174
+ // Try to provide more helpful error information
175
+ const isAbsolute = path.isAbsolute(input);
176
+ const resolvedPath = isAbsolute ? input : path.resolve(process.cwd(), input);
177
+ throw new Error(
178
+ `Video file not found: ${input}\n` +
179
+ `Resolved path: ${resolvedPath}\n` +
180
+ `Is absolute: ${isAbsolute}\n` +
181
+ `CWD: ${process.cwd()}`
182
+ );
158
183
  }
159
184
 
160
185
  // Upload file to Gemini API
@@ -220,16 +245,13 @@ export const geminiTextToImage = {
220
245
  const imageData = part.inlineData.data;
221
246
  if (args.output_path) {
222
247
  const storage = getStorage();
223
- const timestampedPath = generateTimestampedFilename(
224
- args.output_path
225
- );
226
248
  const url = await storage.writeFile(
227
- timestampedPath,
249
+ args.output_path,
228
250
  Buffer.from(imageData, "base64")
229
251
  );
230
252
  images.push({
231
253
  url,
232
- filename: timestampedPath,
254
+ filename: args.output_path,
233
255
  mimeType: "image/png",
234
256
  });
235
257
  }
@@ -301,16 +323,13 @@ export const geminiEditImage = {
301
323
  const imageData = part.inlineData.data;
302
324
  if (args.output_path) {
303
325
  const storage = getStorage();
304
- const timestampedPath = generateTimestampedFilename(
305
- args.output_path
306
- );
307
326
  const url = await storage.writeFile(
308
- timestampedPath,
327
+ args.output_path,
309
328
  Buffer.from(imageData, "base64")
310
329
  );
311
330
  images.push({
312
331
  url,
313
- filename: timestampedPath,
332
+ filename: args.output_path,
314
333
  mimeType: "image/png",
315
334
  });
316
335
  }
@@ -445,12 +464,11 @@ export const geminiSingleSpeakerTts = {
445
464
 
446
465
  const audioBuffer = Buffer.from(data, "base64");
447
466
 
448
- // Generate output filename if not provided
449
- const outputPath = args.output_path || "voice_output.wav";
450
- const timestampedPath = generateTimestampedFilename(outputPath);
467
+ // Use provided output path or generate default with timestamp
468
+ const outputPath = args.output_path || generateTimestampedFilename("voice_output.wav");
451
469
 
452
470
  const storage = getStorage();
453
- const url = await storage.writeFile(timestampedPath, audioBuffer);
471
+ const url = await storage.writeFile(outputPath, audioBuffer);
454
472
 
455
473
  return JSON.stringify({
456
474
  audio: {
@@ -54,9 +54,23 @@ async function fileToBase64(
54
54
  filePath: string
55
55
  ): Promise<{ data: string; mimeType: string }> {
56
56
  const storage = getStorage();
57
- if (!(await storage.exists(filePath))) {
58
- throw new Error(`File not found: ${filePath}`);
57
+
58
+ // Check if file exists
59
+ const exists = await storage.exists(filePath);
60
+ if (!exists) {
61
+ // Try to provide more helpful error information
62
+ const isAbsolute = path.isAbsolute(filePath);
63
+ const resolvedPath = isAbsolute
64
+ ? filePath
65
+ : path.resolve(process.cwd(), filePath);
66
+ throw new Error(
67
+ `File not found: ${filePath}\n` +
68
+ `Resolved path: ${resolvedPath}\n` +
69
+ `Is absolute: ${isAbsolute}\n` +
70
+ `CWD: ${process.cwd()}`
71
+ );
59
72
  }
73
+
60
74
  const buf = await storage.readFile(filePath);
61
75
  const data = Buffer.from(buf).toString("base64");
62
76
  // Default to PNG if not sure, similar to existing code
@@ -288,13 +302,19 @@ export const imageToVideo = {
288
302
  [];
289
303
  const saveVideo = async (base64: string, index: number) => {
290
304
  if (!base64) return;
291
- const baseFilename = args.output_path
292
- ? index === 0
305
+
306
+ // Use provided output path or generate default with timestamp
307
+ let filePath: string;
308
+ if (args.output_path) {
309
+ // User provided path - use as-is for first video, add index for subsequent
310
+ filePath = index === 0
293
311
  ? args.output_path
294
- : args.output_path.replace(/\.mp4$/i, `_${index}.mp4`)
295
- : `video_output${index > 0 ? `_${index}` : ""}.mp4`;
296
-
297
- const filePath = generateTimestampedFilename(baseFilename);
312
+ : args.output_path.replace(/\.mp4$/i, `_${index}.mp4`);
313
+ } else {
314
+ // No path provided - generate timestamped default
315
+ const defaultName = `video_output${index > 0 ? `_${index}` : ""}.mp4`;
316
+ filePath = generateTimestampedFilename(defaultName);
317
+ }
298
318
 
299
319
  const buf = Buffer.from(base64, "base64");
300
320
  const storage = getStorage();
@@ -1,8 +1,11 @@
1
+ import * as path from "path";
2
+
1
3
  /**
2
4
  * Generate a timestamped filename to avoid conflicts
3
5
  * Format: YYYYMMDD_HHmmss_filename.ext
6
+ * Preserves directory structure if present in the input path
4
7
  */
5
- export function generateTimestampedFilename(basename: string): string {
8
+ export function generateTimestampedFilename(filePath: string): string {
6
9
  const now = new Date();
7
10
  const timestamp = now
8
11
  .toISOString()
@@ -10,13 +13,26 @@ export function generateTimestampedFilename(basename: string): string {
10
13
  .replace(/\.\d{3}Z$/, "")
11
14
  .replace("T", "_");
12
15
 
16
+ // Split into directory and filename
17
+ const dir = path.dirname(filePath);
18
+ const basename = path.basename(filePath);
19
+
13
20
  // Extract extension if present
14
21
  const lastDot = basename.lastIndexOf(".");
22
+ let timestampedFilename: string;
23
+
15
24
  if (lastDot > 0) {
16
25
  const name = basename.substring(0, lastDot);
17
26
  const ext = basename.substring(lastDot);
18
- return `${timestamp}_${name}${ext}`;
27
+ timestampedFilename = `${timestamp}_${name}${ext}`;
28
+ } else {
29
+ timestampedFilename = `${timestamp}_${basename}`;
19
30
  }
20
31
 
21
- return `${timestamp}_${basename}`;
32
+ // Reconstruct the full path
33
+ if (dir === ".") {
34
+ return timestampedFilename;
35
+ }
36
+
37
+ return path.join(dir, timestampedFilename);
22
38
  }