@mixio-pro/kalaasetu-mcp 1.0.9 → 1.0.11
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 +1 -1
- package/src/storage/index.ts +1 -0
- package/src/storage/local.ts +6 -1
- package/src/tools/gemini.ts +50 -11
- package/src/tools/image-to-video.ts +16 -2
package/package.json
CHANGED
package/src/storage/index.ts
CHANGED
|
@@ -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;
|
package/src/storage/local.ts
CHANGED
|
@@ -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
|
-
|
|
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> {
|
package/src/tools/gemini.ts
CHANGED
|
@@ -18,9 +18,23 @@ const ai = new GoogleGenAI({
|
|
|
18
18
|
|
|
19
19
|
async function fileToGenerativePart(filePath: string) {
|
|
20
20
|
const storage = getStorage();
|
|
21
|
-
|
|
22
|
-
|
|
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
|
-
|
|
157
|
-
|
|
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
|
|
@@ -167,30 +192,44 @@ async function processVideoInput(
|
|
|
167
192
|
export const geminiTextToImage = {
|
|
168
193
|
name: "generateImage",
|
|
169
194
|
description:
|
|
170
|
-
"Generate images from text prompts using Gemini
|
|
195
|
+
"Generate images from text prompts using Gemini image models with optional reference images",
|
|
171
196
|
parameters: z.object({
|
|
172
197
|
prompt: z.string().describe("Text description of the image to generate"),
|
|
173
198
|
aspect_ratio: z
|
|
174
199
|
.string()
|
|
175
200
|
.optional()
|
|
176
|
-
.describe("Aspect ratio: 1:1, 3:4, 4:3, 9:16, or 16:9"),
|
|
201
|
+
.describe("Aspect ratio: 1:1, 3:4, 4:3, 9:16, or 16:9 (default 9:16)"),
|
|
177
202
|
output_path: z
|
|
178
203
|
.string()
|
|
179
204
|
.optional()
|
|
180
205
|
.describe("File path to save the generated image"),
|
|
206
|
+
reference_images: z
|
|
207
|
+
.array(z.string())
|
|
208
|
+
.optional()
|
|
209
|
+
.describe("Optional reference image file paths to guide generation"),
|
|
181
210
|
}),
|
|
182
211
|
execute: async (args: {
|
|
183
212
|
prompt: string;
|
|
184
213
|
aspect_ratio?: string;
|
|
185
214
|
output_path?: string;
|
|
215
|
+
reference_images?: string[];
|
|
186
216
|
}) => {
|
|
187
217
|
try {
|
|
218
|
+
const contents: any[] = [args.prompt];
|
|
219
|
+
|
|
220
|
+
if (args.reference_images && Array.isArray(args.reference_images)) {
|
|
221
|
+
for (const refPath of args.reference_images) {
|
|
222
|
+
contents.push(await fileToGenerativePart(refPath));
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
188
226
|
const response = await ai.models.generateContent({
|
|
189
|
-
model: "gemini-
|
|
190
|
-
contents:
|
|
227
|
+
model: "gemini-3-pro-image-preview",
|
|
228
|
+
contents: contents,
|
|
191
229
|
config: {
|
|
230
|
+
responseModalities: ["TEXT", "IMAGE"],
|
|
192
231
|
imageConfig: {
|
|
193
|
-
aspectRatio: args.aspect_ratio || "
|
|
232
|
+
aspectRatio: args.aspect_ratio || "9:16",
|
|
194
233
|
},
|
|
195
234
|
},
|
|
196
235
|
});
|
|
@@ -242,7 +281,7 @@ export const geminiTextToImage = {
|
|
|
242
281
|
export const geminiEditImage = {
|
|
243
282
|
name: "editImage",
|
|
244
283
|
description:
|
|
245
|
-
"Edit existing images with text instructions using Gemini
|
|
284
|
+
"Edit existing images with text instructions using Gemini 3 Pro Image Preview",
|
|
246
285
|
parameters: z.object({
|
|
247
286
|
image_path: z.string().describe("Path to the source image file"),
|
|
248
287
|
prompt: z.string().describe("Text instructions for editing the image"),
|
|
@@ -272,7 +311,7 @@ export const geminiEditImage = {
|
|
|
272
311
|
}
|
|
273
312
|
|
|
274
313
|
const response = await ai.models.generateContent({
|
|
275
|
-
model: "gemini-
|
|
314
|
+
model: "gemini-3-pro-image-preview",
|
|
276
315
|
contents: contents,
|
|
277
316
|
});
|
|
278
317
|
|
|
@@ -54,9 +54,23 @@ async function fileToBase64(
|
|
|
54
54
|
filePath: string
|
|
55
55
|
): Promise<{ data: string; mimeType: string }> {
|
|
56
56
|
const storage = getStorage();
|
|
57
|
-
|
|
58
|
-
|
|
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
|