@goonnguyen/human-mcp 2.8.1 → 2.8.2
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/dist/index.js +144 -136
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -168180,6 +168180,68 @@ function estimateImageSize2(base64Data) {
|
|
|
168180
168180
|
// src/tools/hands/index.ts
|
|
168181
168181
|
init_logger();
|
|
168182
168182
|
init_errors();
|
|
168183
|
+
|
|
168184
|
+
// src/utils/response-formatter.ts
|
|
168185
|
+
function formatMediaResponse(result, config, contextText) {
|
|
168186
|
+
const isHttpTransport = config.transport.type === "http" || config.transport.type === "both" && config.transport.http?.enabled;
|
|
168187
|
+
if (isHttpTransport && result.url) {
|
|
168188
|
+
const response = [];
|
|
168189
|
+
response.push({
|
|
168190
|
+
type: "resource",
|
|
168191
|
+
resource: {
|
|
168192
|
+
uri: result.url,
|
|
168193
|
+
mimeType: result.mimeType || "image/png",
|
|
168194
|
+
text: contextText || `Generated media available at: ${result.url}`
|
|
168195
|
+
}
|
|
168196
|
+
});
|
|
168197
|
+
const details = [];
|
|
168198
|
+
if (result.size) {
|
|
168199
|
+
details.push(`Size: ${(result.size / 1024).toFixed(2)} KB`);
|
|
168200
|
+
}
|
|
168201
|
+
if (result.width && result.height) {
|
|
168202
|
+
details.push(`Dimensions: ${result.width}x${result.height}`);
|
|
168203
|
+
}
|
|
168204
|
+
response.push({
|
|
168205
|
+
type: "text",
|
|
168206
|
+
text: `✅ Media generated successfully!
|
|
168207
|
+
|
|
168208
|
+
URL: ${result.url}${details.length > 0 ? `
|
|
168209
|
+
` + details.join(", ") : ""}`
|
|
168210
|
+
});
|
|
168211
|
+
return response;
|
|
168212
|
+
}
|
|
168213
|
+
if (result.base64) {
|
|
168214
|
+
return [
|
|
168215
|
+
{
|
|
168216
|
+
type: "image",
|
|
168217
|
+
data: result.base64,
|
|
168218
|
+
mimeType: result.mimeType || "image/png"
|
|
168219
|
+
},
|
|
168220
|
+
{
|
|
168221
|
+
type: "text",
|
|
168222
|
+
text: contextText || (result.url ? `Image URL: ${result.url}` : "Image generated successfully")
|
|
168223
|
+
}
|
|
168224
|
+
];
|
|
168225
|
+
}
|
|
168226
|
+
if (result.url) {
|
|
168227
|
+
return [
|
|
168228
|
+
{
|
|
168229
|
+
type: "text",
|
|
168230
|
+
text: `${contextText || "Media generated successfully"}
|
|
168231
|
+
|
|
168232
|
+
URL: ${result.url}`
|
|
168233
|
+
}
|
|
168234
|
+
];
|
|
168235
|
+
}
|
|
168236
|
+
return [
|
|
168237
|
+
{
|
|
168238
|
+
type: "text",
|
|
168239
|
+
text: contextText || "Media generated successfully"
|
|
168240
|
+
}
|
|
168241
|
+
];
|
|
168242
|
+
}
|
|
168243
|
+
|
|
168244
|
+
// src/tools/hands/index.ts
|
|
168183
168245
|
async function registerHandsTool(server, config) {
|
|
168184
168246
|
const geminiClient = new GeminiClient(config);
|
|
168185
168247
|
server.registerTool("gemini_gen_image", {
|
|
@@ -168459,21 +168521,16 @@ async function handleImageGeneration(geminiClient, args, config) {
|
|
|
168459
168521
|
filePrefix: "gemini-image"
|
|
168460
168522
|
};
|
|
168461
168523
|
const result = await generateImage(geminiClient, generationOptions, config);
|
|
168524
|
+
let base64Data;
|
|
168525
|
+
let mimeType;
|
|
168462
168526
|
if (result.imageData.startsWith("data:")) {
|
|
168463
168527
|
const matches = result.imageData.match(/data:([^;]+);base64,(.+)/);
|
|
168464
168528
|
if (matches && matches[1] && matches[2]) {
|
|
168465
|
-
|
|
168466
|
-
|
|
168467
|
-
|
|
168468
|
-
|
|
168469
|
-
|
|
168470
|
-
type: "image",
|
|
168471
|
-
data: base64Data,
|
|
168472
|
-
mimeType
|
|
168473
|
-
},
|
|
168474
|
-
{
|
|
168475
|
-
type: "text",
|
|
168476
|
-
text: `✅ Image generated successfully using ${result.model}
|
|
168529
|
+
mimeType = matches[1];
|
|
168530
|
+
base64Data = matches[2];
|
|
168531
|
+
}
|
|
168532
|
+
}
|
|
168533
|
+
const contextText = `✅ Image generated successfully using ${result.model}
|
|
168477
168534
|
|
|
168478
168535
|
**Generation Details:**
|
|
168479
168536
|
- Prompt: "${prompt}"
|
|
@@ -168487,35 +168544,16 @@ async function handleImageGeneration(geminiClient, args, config) {
|
|
|
168487
168544
|
- File Path: ${result.filePath}
|
|
168488
168545
|
- File Name: ${result.fileName}
|
|
168489
168546
|
- File Size: ${result.fileSize} bytes` : ""}${result.fileUrl ? `
|
|
168490
|
-
- Public URL: ${result.fileUrl}` : ""}
|
|
168491
|
-
|
|
168492
|
-
|
|
168493
|
-
|
|
168494
|
-
|
|
168495
|
-
|
|
168496
|
-
|
|
168547
|
+
- Public URL: ${result.fileUrl}` : ""}`;
|
|
168548
|
+
const formattedResponse = formatMediaResponse({
|
|
168549
|
+
url: result.fileUrl,
|
|
168550
|
+
filePath: result.filePath,
|
|
168551
|
+
base64: base64Data,
|
|
168552
|
+
mimeType,
|
|
168553
|
+
size: result.fileSize
|
|
168554
|
+
}, config, contextText);
|
|
168497
168555
|
return {
|
|
168498
|
-
content:
|
|
168499
|
-
{
|
|
168500
|
-
type: "text",
|
|
168501
|
-
text: `✅ Image generated successfully!
|
|
168502
|
-
|
|
168503
|
-
**Generation Details:**
|
|
168504
|
-
- Prompt: "${prompt}"
|
|
168505
|
-
- Model: ${result.model}
|
|
168506
|
-
- Format: ${result.format}
|
|
168507
|
-
- Size: ${result.size}
|
|
168508
|
-
- Generation Time: ${result.generationTime}ms${result.filePath ? `
|
|
168509
|
-
|
|
168510
|
-
**File Information:**
|
|
168511
|
-
- File Path: ${result.filePath}
|
|
168512
|
-
- File Name: ${result.fileName}
|
|
168513
|
-
- File Size: ${result.fileSize} bytes` : ""}${result.fileUrl ? `
|
|
168514
|
-
- Public URL: ${result.fileUrl}` : ""}
|
|
168515
|
-
|
|
168516
|
-
**Image Data:** ${result.imageData.substring(0, 100)}...`
|
|
168517
|
-
}
|
|
168518
|
-
],
|
|
168556
|
+
content: formattedResponse,
|
|
168519
168557
|
isError: false
|
|
168520
168558
|
};
|
|
168521
168559
|
}
|
|
@@ -168540,34 +168578,32 @@ async function handleVideoGeneration(geminiClient, args, config) {
|
|
|
168540
168578
|
filePrefix: "gemini-video"
|
|
168541
168579
|
};
|
|
168542
168580
|
const result = await generateVideo(geminiClient, generationOptions, config);
|
|
168581
|
+
const contextText = `✅ Video generated successfully!
|
|
168582
|
+
|
|
168583
|
+
**Generation Details:**
|
|
168584
|
+
- Prompt: "${prompt}"
|
|
168585
|
+
- Model: ${result.model}
|
|
168586
|
+
- Format: ${result.format}
|
|
168587
|
+
- Duration: ${result.duration}
|
|
168588
|
+
- Aspect Ratio: ${result.aspectRatio}
|
|
168589
|
+
- FPS: ${result.fps}
|
|
168590
|
+
- Generation Time: ${result.generationTime}ms
|
|
168591
|
+
- Operation ID: ${result.operationId}
|
|
168592
|
+
- Timestamp: ${new Date().toISOString()}${result.filePath ? `
|
|
168593
|
+
|
|
168594
|
+
**File Information:**
|
|
168595
|
+
- File Path: ${result.filePath}
|
|
168596
|
+
- File Name: ${result.fileName}
|
|
168597
|
+
- File Size: ${result.fileSize} bytes` : ""}${result.fileUrl ? `
|
|
168598
|
+
- Public URL: ${result.fileUrl}` : ""}`;
|
|
168599
|
+
const formattedResponse = formatMediaResponse({
|
|
168600
|
+
url: result.fileUrl,
|
|
168601
|
+
filePath: result.filePath,
|
|
168602
|
+
mimeType: `video/${result.format}`,
|
|
168603
|
+
size: result.fileSize
|
|
168604
|
+
}, config, contextText);
|
|
168543
168605
|
return {
|
|
168544
|
-
content:
|
|
168545
|
-
{
|
|
168546
|
-
type: "text",
|
|
168547
|
-
text: JSON.stringify({
|
|
168548
|
-
success: true,
|
|
168549
|
-
video: result.filePath ? `File saved to: ${result.filePath}` : result.videoData.substring(0, 100) + "...",
|
|
168550
|
-
format: result.format,
|
|
168551
|
-
model: result.model,
|
|
168552
|
-
prompt,
|
|
168553
|
-
operation_id: result.operationId,
|
|
168554
|
-
file_info: result.filePath ? {
|
|
168555
|
-
file_path: result.filePath,
|
|
168556
|
-
file_name: result.fileName,
|
|
168557
|
-
file_size: result.fileSize,
|
|
168558
|
-
public_url: result.fileUrl
|
|
168559
|
-
} : null,
|
|
168560
|
-
metadata: {
|
|
168561
|
-
timestamp: new Date().toISOString(),
|
|
168562
|
-
generation_time: result.generationTime,
|
|
168563
|
-
duration: result.duration,
|
|
168564
|
-
aspect_ratio: result.aspectRatio,
|
|
168565
|
-
fps: result.fps,
|
|
168566
|
-
size: result.size
|
|
168567
|
-
}
|
|
168568
|
-
}, null, 2)
|
|
168569
|
-
}
|
|
168570
|
-
],
|
|
168606
|
+
content: formattedResponse,
|
|
168571
168607
|
isError: false
|
|
168572
168608
|
};
|
|
168573
168609
|
}
|
|
@@ -168603,35 +168639,32 @@ async function handleImageToVideoGeneration(geminiClient, args, config) {
|
|
|
168603
168639
|
filePrefix: "gemini-image-to-video"
|
|
168604
168640
|
};
|
|
168605
168641
|
const result = await generateImageToVideo(geminiClient, prompt, image_input, generationOptions, config);
|
|
168642
|
+
const contextText = `✅ Video generated from image successfully!
|
|
168643
|
+
|
|
168644
|
+
**Generation Details:**
|
|
168645
|
+
- Prompt: "${prompt}"
|
|
168646
|
+
- Model: ${result.model}
|
|
168647
|
+
- Format: ${result.format}
|
|
168648
|
+
- Duration: ${result.duration}
|
|
168649
|
+
- Aspect Ratio: ${result.aspectRatio}
|
|
168650
|
+
- FPS: ${result.fps}
|
|
168651
|
+
- Generation Time: ${result.generationTime}ms
|
|
168652
|
+
- Operation ID: ${result.operationId}
|
|
168653
|
+
- Timestamp: ${new Date().toISOString()}${result.filePath ? `
|
|
168654
|
+
|
|
168655
|
+
**File Information:**
|
|
168656
|
+
- File Path: ${result.filePath}
|
|
168657
|
+
- File Name: ${result.fileName}
|
|
168658
|
+
- File Size: ${result.fileSize} bytes` : ""}${result.fileUrl ? `
|
|
168659
|
+
- Public URL: ${result.fileUrl}` : ""}`;
|
|
168660
|
+
const formattedResponse = formatMediaResponse({
|
|
168661
|
+
url: result.fileUrl,
|
|
168662
|
+
filePath: result.filePath,
|
|
168663
|
+
mimeType: `video/${result.format}`,
|
|
168664
|
+
size: result.fileSize
|
|
168665
|
+
}, config, contextText);
|
|
168606
168666
|
return {
|
|
168607
|
-
content:
|
|
168608
|
-
{
|
|
168609
|
-
type: "text",
|
|
168610
|
-
text: JSON.stringify({
|
|
168611
|
-
success: true,
|
|
168612
|
-
video: result.filePath ? `File saved to: ${result.filePath}` : result.videoData.substring(0, 100) + "...",
|
|
168613
|
-
format: result.format,
|
|
168614
|
-
model: result.model,
|
|
168615
|
-
prompt,
|
|
168616
|
-
image_input,
|
|
168617
|
-
operation_id: result.operationId,
|
|
168618
|
-
file_info: result.filePath ? {
|
|
168619
|
-
file_path: result.filePath,
|
|
168620
|
-
file_name: result.fileName,
|
|
168621
|
-
file_size: result.fileSize,
|
|
168622
|
-
public_url: result.fileUrl
|
|
168623
|
-
} : null,
|
|
168624
|
-
metadata: {
|
|
168625
|
-
timestamp: new Date().toISOString(),
|
|
168626
|
-
generation_time: result.generationTime,
|
|
168627
|
-
duration: result.duration,
|
|
168628
|
-
aspect_ratio: result.aspectRatio,
|
|
168629
|
-
fps: result.fps,
|
|
168630
|
-
size: result.size
|
|
168631
|
-
}
|
|
168632
|
-
}, null, 2)
|
|
168633
|
-
}
|
|
168634
|
-
],
|
|
168667
|
+
content: formattedResponse,
|
|
168635
168668
|
isError: false
|
|
168636
168669
|
};
|
|
168637
168670
|
}
|
|
@@ -168689,21 +168722,16 @@ async function handleImageEditing(geminiClient, args, config) {
|
|
|
168689
168722
|
filePrefix: `edited-${operation}`
|
|
168690
168723
|
};
|
|
168691
168724
|
const result = await editImage(geminiClient, editingOptions, config);
|
|
168725
|
+
let base64Data;
|
|
168726
|
+
let mimeType;
|
|
168692
168727
|
if (result.editedImageData.startsWith("data:")) {
|
|
168693
168728
|
const matches = result.editedImageData.match(/data:([^;]+);base64,(.+)/);
|
|
168694
168729
|
if (matches && matches[1] && matches[2]) {
|
|
168695
|
-
|
|
168696
|
-
|
|
168697
|
-
|
|
168698
|
-
|
|
168699
|
-
|
|
168700
|
-
type: "image",
|
|
168701
|
-
data: base64Data,
|
|
168702
|
-
mimeType
|
|
168703
|
-
},
|
|
168704
|
-
{
|
|
168705
|
-
type: "text",
|
|
168706
|
-
text: `✅ Image edited successfully using ${operation} operation
|
|
168730
|
+
mimeType = matches[1];
|
|
168731
|
+
base64Data = matches[2];
|
|
168732
|
+
}
|
|
168733
|
+
}
|
|
168734
|
+
const contextText = `✅ Image edited successfully using ${operation} operation
|
|
168707
168735
|
|
|
168708
168736
|
**Editing Details:**
|
|
168709
168737
|
- Operation: ${operation}
|
|
@@ -168724,36 +168752,16 @@ async function handleImageEditing(geminiClient, args, config) {
|
|
|
168724
168752
|
**Operation Metadata:**
|
|
168725
168753
|
- Strength: ${result.metadata.strength}
|
|
168726
168754
|
- Guidance Scale: ${result.metadata.guidanceScale}
|
|
168727
|
-
- Seed: ${result.metadata.seed || "random"}` : ""}
|
|
168728
|
-
|
|
168729
|
-
|
|
168730
|
-
|
|
168731
|
-
|
|
168732
|
-
|
|
168733
|
-
|
|
168755
|
+
- Seed: ${result.metadata.seed || "random"}` : ""}`;
|
|
168756
|
+
const formattedResponse = formatMediaResponse({
|
|
168757
|
+
url: result.fileUrl,
|
|
168758
|
+
filePath: result.filePath,
|
|
168759
|
+
base64: base64Data,
|
|
168760
|
+
mimeType,
|
|
168761
|
+
size: result.fileSize
|
|
168762
|
+
}, config, contextText);
|
|
168734
168763
|
return {
|
|
168735
|
-
content:
|
|
168736
|
-
{
|
|
168737
|
-
type: "text",
|
|
168738
|
-
text: `✅ Image edited successfully!
|
|
168739
|
-
|
|
168740
|
-
**Editing Details:**
|
|
168741
|
-
- Operation: ${operation}
|
|
168742
|
-
- Prompt: "${prompt}"
|
|
168743
|
-
- Format: ${result.format}
|
|
168744
|
-
- Original Size: ${result.originalSize}
|
|
168745
|
-
- Edited Size: ${result.editedSize}
|
|
168746
|
-
- Processing Time: ${result.processingTime}ms${result.filePath ? `
|
|
168747
|
-
|
|
168748
|
-
**File Information:**
|
|
168749
|
-
- File Path: ${result.filePath}
|
|
168750
|
-
- File Name: ${result.fileName}
|
|
168751
|
-
- File Size: ${result.fileSize} bytes` : ""}${result.fileUrl ? `
|
|
168752
|
-
- Public URL: ${result.fileUrl}` : ""}
|
|
168753
|
-
|
|
168754
|
-
**Edited Image Data:** ${result.editedImageData.substring(0, 100)}...`
|
|
168755
|
-
}
|
|
168756
|
-
],
|
|
168764
|
+
content: formattedResponse,
|
|
168757
168765
|
isError: false
|
|
168758
168766
|
};
|
|
168759
168767
|
}
|