Switch AI tool generator from Gemini to local Ollama (gemma4:26b @ shadow-death .128)
This commit is contained in:
@@ -1,16 +1,31 @@
|
|||||||
import { GoogleGenAI } from '@google/genai';
|
|
||||||
import { MCPServerDefinition, ToolDefinition } from '../types.js';
|
import { MCPServerDefinition, ToolDefinition } from '../types.js';
|
||||||
|
|
||||||
let aiClient: GoogleGenAI | null = null;
|
const OLLAMA_HOST = process.env.OLLAMA_HOST || 'http://10.30.20.128:11434';
|
||||||
|
const OLLAMA_MODEL = process.env.OLLAMA_MODEL || 'gemma4:26b';
|
||||||
|
|
||||||
function getAIClient(): GoogleGenAI | null {
|
async function callLocalModel(prompt: string): Promise<string> {
|
||||||
if (!aiClient) {
|
const res = await fetch(`${OLLAMA_HOST}/api/chat`, {
|
||||||
const key = process.env.GEMINI_API_KEY;
|
method: 'POST',
|
||||||
if (key && key !== 'MY_GEMINI_API_KEY') {
|
headers: { 'Content-Type': 'application/json' },
|
||||||
aiClient = new GoogleGenAI({ apiKey: key });
|
body: JSON.stringify({
|
||||||
}
|
model: OLLAMA_MODEL,
|
||||||
|
messages: [{ role: 'user', content: prompt }],
|
||||||
|
stream: false,
|
||||||
|
format: 'json',
|
||||||
|
keep_alive: '30m',
|
||||||
|
options: { num_predict: 4096, temperature: 0.2 },
|
||||||
|
}),
|
||||||
|
signal: AbortSignal.timeout(180000),
|
||||||
|
});
|
||||||
|
if (!res.ok) {
|
||||||
|
throw new Error(`Ollama HTTP ${res.status} (${res.statusText})`);
|
||||||
}
|
}
|
||||||
return aiClient;
|
const data = await res.json();
|
||||||
|
let content = data?.message?.content || '';
|
||||||
|
if (!content) content = data?.message?.thinking || '';
|
||||||
|
content = content.trim();
|
||||||
|
if (!content) throw new Error('Empty response from local model');
|
||||||
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GeneratedMCPResponse {
|
export interface GeneratedMCPResponse {
|
||||||
@@ -36,17 +51,8 @@ export interface GeneratedMCPResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function generateMCPToolFromPrompt(prompt: string): Promise<GeneratedMCPResponse> {
|
export async function generateMCPToolFromPrompt(prompt: string): Promise<GeneratedMCPResponse> {
|
||||||
const ai = getAIClient();
|
|
||||||
|
|
||||||
if (!ai) {
|
|
||||||
// Fallback template generator when GEMINI_API_KEY is not configured
|
|
||||||
return generateFallbackMCP(prompt);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await ai.models.generateContent({
|
const systemPrompt = `You are an expert Model Context Protocol (MCP) tool builder.
|
||||||
model: 'gemini-2.5-flash',
|
|
||||||
contents: `You are an expert Model Context Protocol (MCP) tool builder.
|
|
||||||
Given the following user request or API prompt, construct a complete MCP Tool configuration in strict JSON.
|
Given the following user request or API prompt, construct a complete MCP Tool configuration in strict JSON.
|
||||||
|
|
||||||
User Request: "${prompt}"
|
User Request: "${prompt}"
|
||||||
@@ -75,15 +81,14 @@ Respond ONLY with valid JSON (no markdown ticks or commentary) matching this Typ
|
|||||||
"sampleArgs": { "param1": "sample_value" }
|
"sampleArgs": { "param1": "sample_value" }
|
||||||
}
|
}
|
||||||
|
|
||||||
Provide executable JavaScript code for customScript or accurate URL template for webhookConfig. Use fetch() if HTTP calls are needed inside customScript.`,
|
Provide executable JavaScript code for customScript or accurate URL template for webhookConfig. Use fetch() if HTTP calls are needed inside customScript.`;
|
||||||
});
|
|
||||||
|
|
||||||
const rawText = response.text || '';
|
const rawText = await callLocalModel(systemPrompt);
|
||||||
const cleanJson = rawText.replace(/```json/g, '').replace(/```/g, '').trim();
|
const cleanJson = rawText.replace(/```json/g, '').replace(/```/g, '').trim();
|
||||||
const parsed = JSON.parse(cleanJson);
|
const parsed = JSON.parse(cleanJson);
|
||||||
return parsed;
|
return parsed;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.warn('Gemini API call failed, using heuristic fallback:', err);
|
console.warn('Local model generation failed, using heuristic fallback:', err);
|
||||||
return generateFallbackMCP(prompt);
|
return generateFallbackMCP(prompt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user