gemini-flow
Version:
🧠 Gemini Flow - AI-Powered Development Orchestration with Google Gemini API Integration
338 lines (308 loc) • 10 kB
JavaScript
const path = require('path');
const fs = require('fs');
const { spawn } = require('child_process');
const DATA_DIR = process.env.GEMINI_FLOW_DATA_DIR || path.join(__dirname, '..', '.gemini-flow');
// Ensure data directory exists
if (!fs.existsSync(DATA_DIR)) {
fs.mkdirSync(DATA_DIR, { recursive: true });
}
const commands = process.argv.slice(2);
if (commands.length === 0) {
console.log('🐝 Gemini Flow v2.0.0 - AI Swarm Orchestration');
console.log('');
console.log('Usage:');
console.log(' gemini-flow mcp start - Start MCP server');
console.log(' gemini-flow swarm init - Initialize swarm');
console.log(' gemini-flow --help - Show help');
process.exit(0);
}
// MCP Server Command
if (commands[0] === 'mcp' && commands[1] === 'start') {
console.error('🚀 Starting Gemini Flow MCP Server...');
// Simple MCP Server implementation
const mcpServer = {
tools: [
{
name: 'mcp__gemini-flow__swarm_init',
description: 'Initialize a new swarm with specified topology',
inputSchema: {
type: 'object',
properties: {
topology: {
type: 'string',
enum: ['mesh', 'hierarchical', 'ring', 'star'],
description: 'Swarm topology type'
},
maxAgents: {
type: 'number',
default: 5,
minimum: 1,
maximum: 100,
description: 'Maximum number of agents'
},
strategy: {
type: 'string',
default: 'balanced',
enum: ['balanced', 'specialized', 'adaptive'],
description: 'Distribution strategy'
}
},
required: ['topology']
}
},
{
name: 'mcp__gemini-flow__agent_spawn',
description: 'Spawn a new agent in the swarm',
inputSchema: {
type: 'object',
properties: {
type: {
type: 'string',
enum: ['researcher', 'coder', 'analyst', 'optimizer', 'coordinator'],
description: 'Agent type'
},
name: {
type: 'string',
description: 'Custom agent name'
},
capabilities: {
type: 'array',
items: { type: 'string' },
description: 'Agent capabilities'
}
},
required: ['type']
}
},
{
name: 'mcp__gemini-flow__task_orchestrate',
description: 'Orchestrate a task across the swarm',
inputSchema: {
type: 'object',
properties: {
task: {
type: 'string',
description: 'Task description or instructions'
},
strategy: {
type: 'string',
default: 'adaptive',
enum: ['parallel', 'sequential', 'adaptive'],
description: 'Execution strategy'
},
priority: {
type: 'string',
default: 'medium',
enum: ['low', 'medium', 'high', 'critical'],
description: 'Task priority'
},
maxAgents: {
type: 'number',
minimum: 1,
maximum: 10,
description: 'Maximum agents to use'
}
},
required: ['task']
}
},
{
name: 'mcp__gemini-flow__memory_usage',
description: 'Store/retrieve persistent memory with TTL and namespacing',
inputSchema: {
type: 'object',
properties: {
action: {
type: 'string',
enum: ['store', 'retrieve', 'list', 'delete', 'search'],
description: 'Memory action to perform'
},
key: {
type: 'string',
description: 'Memory key'
},
value: {
type: 'string',
description: 'Value to store'
},
namespace: {
type: 'string',
default: 'default',
description: 'Memory namespace'
},
ttl: {
type: 'number',
description: 'Time to live in seconds'
}
},
required: ['action']
}
},
{
name: 'mcp__gemini-flow__swarm_status',
description: 'Get current swarm status and agent information',
inputSchema: {
type: 'object',
properties: {
swarmId: {
type: 'string',
description: 'Specific swarm ID'
}
}
}
}
]
};
// MCP Server ready, wait for initialization
console.error('📤 MCP Server ready, waiting for initialize...');
// Keep server alive and handle requests
process.stdin.setEncoding('utf8');
let buffer = '';
process.stdin.on('data', (chunk) => {
console.error('📨 Received data:', chunk.slice(0, 100) + '...');
buffer += chunk;
// Process complete JSON messages
let lines = buffer.split('\n');
buffer = lines.pop() || ''; // Keep incomplete line in buffer
for (let line of lines) {
if (line.trim()) {
try {
const request = JSON.parse(line);
console.error('🔍 Processing request:', request.method);
if (request.method === 'initialize') {
console.error('🤝 Handling initialize request');
const response = {
jsonrpc: '2.0',
id: request.id,
result: {
capabilities: {
tools: {}
},
serverInfo: {
name: 'gemini-flow',
version: '2.0.0'
}
}
};
process.stdout.write(JSON.stringify(response) + '\n');
console.error('✅ Sent initialize response');
} else if (request.method === 'tools/list') {
console.error('📋 Handling tools/list request');
const response = {
jsonrpc: '2.0',
id: request.id,
result: {
tools: mcpServer.tools
}
};
process.stdout.write(JSON.stringify(response) + '\n');
console.error('✅ Sent tools list:', mcpServer.tools.length, 'tools');
} else if (request.method === 'tools/call') {
// Handle tool calls
const toolName = request.params.name;
const args = request.params.arguments || {};
console.error('🛠️ Calling tool:', toolName);
const result = handleToolCall(toolName, args);
const response = {
jsonrpc: '2.0',
id: request.id,
result: {
content: [
{
type: 'text',
text: JSON.stringify(result, null, 2)
}
]
}
};
process.stdout.write(JSON.stringify(response) + '\n');
}
} catch (error) {
console.error('❌ Parse error:', error.message);
const errorResponse = {
jsonrpc: '2.0',
id: null,
error: {
code: -32700,
message: 'Parse error',
data: error.message
}
};
process.stdout.write(JSON.stringify(errorResponse) + '\n');
}
}
}
});
process.stdin.on('end', () => {
console.error('📪 STDIN closed, exiting...');
process.exit(0);
});
return;
}
function handleToolCall(toolName, args) {
const timestamp = Date.now();
switch (toolName) {
case 'mcp__gemini-flow__swarm_init':
return {
swarmId: `swarm-${timestamp}`,
topology: args.topology,
maxAgents: args.maxAgents || 5,
strategy: args.strategy || 'balanced',
status: 'initialized',
agents: [],
created: timestamp
};
case 'mcp__gemini-flow__agent_spawn':
return {
agentId: `agent-${args.type}-${timestamp}`,
type: args.type,
name: args.name || `${args.type}-agent`,
capabilities: args.capabilities || [args.type, 'coordination'],
status: 'active',
created: timestamp
};
case 'mcp__gemini-flow__task_orchestrate':
return {
taskId: `task-${timestamp}`,
task: args.task,
strategy: args.strategy || 'adaptive',
priority: args.priority || 'medium',
status: 'orchestrating',
agents: [],
started: timestamp
};
case 'mcp__gemini-flow__memory_usage':
if (args.action === 'store') {
// Store in memory file
const memoryFile = path.join(DATA_DIR, 'memory', 'gemini-flow-data.json');
let memory = {};
if (fs.existsSync(memoryFile)) {
memory = JSON.parse(fs.readFileSync(memoryFile, 'utf8'));
}
if (!memory.memory) memory.memory = {};
memory.memory[args.key] = {
value: args.value,
timestamp: timestamp,
ttl: args.ttl || 3600000
};
fs.mkdirSync(path.dirname(memoryFile), { recursive: true });
fs.writeFileSync(memoryFile, JSON.stringify(memory, null, 2));
return { stored: args.key, timestamp: timestamp };
}
break;
case 'mcp__gemini-flow__swarm_status':
return {
status: 'active',
swarms: 1,
agents: 4,
tasks: 1,
uptime: Math.floor(process.uptime()),
version: '2.0.0'
};
default:
return { error: `Unknown tool: ${toolName}` };
}
}
console.log('Unknown command:', commands.join(' '));
process.exit(1);