@fre4x/gemini 1.0.49 → 1.0.51

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 (2) hide show
  1. package/dist/index.js +105 -56
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -67523,6 +67523,24 @@ function getAi() {
67523
67523
  }
67524
67524
  return ai;
67525
67525
  }
67526
+ function createVideoOperation(name) {
67527
+ const operation = new GenerateVideosOperation();
67528
+ operation.name = name;
67529
+ return operation;
67530
+ }
67531
+ function withApiKey(videoUrl) {
67532
+ const apiKey = getApiKey();
67533
+ try {
67534
+ const url2 = new URL(videoUrl);
67535
+ if (!url2.searchParams.has("key")) {
67536
+ url2.searchParams.set("key", apiKey);
67537
+ }
67538
+ return url2.toString();
67539
+ } catch {
67540
+ const separator = videoUrl.includes("?") ? "&" : "?";
67541
+ return `${videoUrl}${separator}key=${encodeURIComponent(apiKey)}`;
67542
+ }
67543
+ }
67526
67544
  var FILE_EXT_TO_MIME = {
67527
67545
  ".png": "image/png",
67528
67546
  ".jpg": "image/jpeg",
@@ -67565,6 +67583,10 @@ var ANALYZE_MEDIA_TOOL = {
67565
67583
  type: "string",
67566
67584
  default: DEFAULT_TEXT_MODEL,
67567
67585
  description: "Gemini model to use for analysis."
67586
+ },
67587
+ output_dir: {
67588
+ type: "string",
67589
+ description: "Optional directory to save the analysis result as a .txt file."
67568
67590
  }
67569
67591
  },
67570
67592
  required: ["media_source"]
@@ -67754,14 +67776,15 @@ async function analyzeMedia(rawArgs) {
67754
67776
  prompt: z3.string().min(1).default("Describe this media."),
67755
67777
  media_source: z3.string().min(1),
67756
67778
  mime_type: z3.string().optional(),
67757
- model: z3.string().optional().default(DEFAULT_TEXT_MODEL)
67779
+ model: z3.string().optional().default(DEFAULT_TEXT_MODEL),
67780
+ output_dir: z3.string().optional()
67758
67781
  }).strict(),
67759
67782
  rawArgs
67760
67783
  );
67761
67784
  if (!parsed.success) {
67762
67785
  return parsed.error;
67763
67786
  }
67764
- const { prompt, media_source, mime_type, model } = parsed.data;
67787
+ const { prompt, media_source, mime_type, model, output_dir } = parsed.data;
67765
67788
  let media;
67766
67789
  try {
67767
67790
  media = await resolveMediaSource(media_source, mime_type);
@@ -67771,34 +67794,46 @@ async function analyzeMedia(rawArgs) {
67771
67794
  error48 instanceof Error ? error48.message : String(error48)
67772
67795
  );
67773
67796
  }
67797
+ let responseText;
67774
67798
  if (IS_MOCK) {
67775
- return textResult(
67776
- `[Mock] Analyzed media (${media.mimeType})
67799
+ responseText = `[Mock] Analyzed media (${media.mimeType})
67777
67800
  Source: ${media.label}
67778
67801
  Prompt: "${prompt}"
67779
67802
  Model: ${model}
67780
67803
 
67781
- Mock response \u2014 no API call made.`
67804
+ Mock response \u2014 no API call made.`;
67805
+ } else {
67806
+ const response = await getAi().models.generateContent({
67807
+ model,
67808
+ contents: [
67809
+ {
67810
+ role: "user",
67811
+ parts: [
67812
+ { text: prompt },
67813
+ {
67814
+ inlineData: {
67815
+ data: media.data,
67816
+ mimeType: media.mimeType
67817
+ }
67818
+ }
67819
+ ]
67820
+ }
67821
+ ]
67822
+ });
67823
+ responseText = response.text || "No analysis generated.";
67824
+ }
67825
+ if (output_dir) {
67826
+ const fname = `analysis-${Date.now()}.txt`;
67827
+ const fpath = path2.join(output_dir, fname);
67828
+ await fs3.mkdir(output_dir, { recursive: true });
67829
+ await fs3.writeFile(fpath, responseText);
67830
+ return textResult(
67831
+ `${responseText}
67832
+
67833
+ \u2705 Analysis result saved to: ${fpath}`
67782
67834
  );
67783
67835
  }
67784
- const response = await getAi().models.generateContent({
67785
- model,
67786
- contents: [
67787
- {
67788
- role: "user",
67789
- parts: [
67790
- { text: prompt },
67791
- {
67792
- inlineData: {
67793
- data: media.data,
67794
- mimeType: media.mimeType
67795
- }
67796
- }
67797
- ]
67798
- }
67799
- ]
67800
- });
67801
- return textResult(response.text || "No analysis generated.");
67836
+ return textResult(responseText);
67802
67837
  }
67803
67838
  async function listModels(rawArgs) {
67804
67839
  const parsed = parseArgs(
@@ -68004,26 +68039,21 @@ async function getVideoStatus(rawArgs) {
68004
68039
  return parsed.error;
68005
68040
  }
68006
68041
  const { operation_name, output_dir } = parsed.data;
68042
+ let op;
68007
68043
  if (IS_MOCK) {
68008
- const lines2 = [
68009
- `[Mock] Operation: ${operation_name}`,
68010
- "done: true",
68011
- "Video URL: https://example.com/mock-video.mp4"
68012
- ];
68013
- if (output_dir) {
68014
- const fname = `video-${Date.now()}.mp4`;
68015
- const fpath = path2.join(output_dir, fname);
68016
- await fs3.mkdir(output_dir, { recursive: true });
68017
- await fs3.writeFile(fpath, "[mock video data]");
68018
- lines2.push(`Saved to: ${fpath}`);
68019
- }
68020
- return textResult(lines2.join("\n"));
68044
+ op = {
68045
+ done: true,
68046
+ response: {
68047
+ generatedVideos: [
68048
+ { video: { uri: "https://example.com/mock-video.mp4" } }
68049
+ ]
68050
+ }
68051
+ };
68052
+ } else {
68053
+ op = await getAi().operations.getVideosOperation({
68054
+ operation: createVideoOperation(operation_name)
68055
+ });
68021
68056
  }
68022
- const op = await getAi().operations.getVideosOperation({
68023
- operation: {
68024
- name: operation_name
68025
- }
68026
- });
68027
68057
  if (!op.done) {
68028
68058
  return textResult(
68029
68059
  `Operation ${operation_name} is still in progress. Check back in ~30 seconds.`
@@ -68048,25 +68078,39 @@ ${JSON.stringify(op.response, null, 2)}`
68048
68078
  );
68049
68079
  }
68050
68080
  const savedPaths = [];
68051
- if (output_dir) {
68052
- await fs3.mkdir(output_dir, { recursive: true });
68053
- const paths = await Promise.all(
68054
- videos.map(async (url2, index) => {
68055
- const fname = `video-${Date.now()}-${index + 1}.mp4`;
68056
- const fpath = path2.join(output_dir, fname);
68057
- const videoResp = await fetch(url2);
68081
+ const videoContents = [];
68082
+ await Promise.all(
68083
+ videos.map(async (url2, index) => {
68084
+ let buffer;
68085
+ if (IS_MOCK) {
68086
+ buffer = Buffer.from("[mock video data]");
68087
+ } else {
68088
+ const videoResp = await fetch(withApiKey(url2));
68058
68089
  if (!videoResp.ok) {
68059
68090
  throw new Error(
68060
68091
  `Failed to download video: ${videoResp.status}`
68061
68092
  );
68062
68093
  }
68063
- const buf = await videoResp.arrayBuffer();
68064
- await fs3.writeFile(fpath, Buffer.from(buf));
68065
- return fpath;
68066
- })
68067
- );
68068
- savedPaths.push(...paths);
68069
- }
68094
+ const arrayBuffer = await videoResp.arrayBuffer();
68095
+ buffer = Buffer.from(arrayBuffer);
68096
+ }
68097
+ videoContents.push({
68098
+ type: "resource",
68099
+ resource: {
68100
+ uri: url2,
68101
+ mimeType: "video/mp4",
68102
+ blob: buffer.toString("base64")
68103
+ }
68104
+ });
68105
+ if (output_dir) {
68106
+ const fname = `video-${Date.now()}-${index + 1}.mp4`;
68107
+ const fpath = path2.join(output_dir, fname);
68108
+ await fs3.mkdir(output_dir, { recursive: true });
68109
+ await fs3.writeFile(fpath, buffer);
68110
+ savedPaths.push(fpath);
68111
+ }
68112
+ })
68113
+ );
68070
68114
  const lines = [
68071
68115
  `Video generation complete!
68072
68116
 
@@ -68078,7 +68122,12 @@ ${videos.join("\n")}`
68078
68122
  Saved to:
68079
68123
  ${savedPaths.join("\n")}`);
68080
68124
  }
68081
- return textResult(lines.join(""));
68125
+ return {
68126
+ content: [
68127
+ { type: "text", text: lines.join("") },
68128
+ ...videoContents
68129
+ ]
68130
+ };
68082
68131
  }
68083
68132
  async function handleToolCall(name, args) {
68084
68133
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fre4x/gemini",
3
- "version": "1.0.49",
3
+ "version": "1.0.51",
4
4
  "description": "A Gemini MCP server providing multimodal analysis and image/video generation.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",