Switch AI tool generator from Gemini to local Ollama (gemma4:26b @ shadow-death .128)

This commit is contained in:
drjones
2026-08-13 23:45:02 +00:00
parent 33a9957dcc
commit d1210773e7

View File

@@ -1,16 +1,31 @@
import { GoogleGenAI } from '@google/genai';
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 {
if (!aiClient) {
const key = process.env.GEMINI_API_KEY;
if (key && key !== 'MY_GEMINI_API_KEY') {
aiClient = new GoogleGenAI({ apiKey: key });
}
async function callLocalModel(prompt: string): Promise<string> {
const res = await fetch(`${OLLAMA_HOST}/api/chat`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
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 {
@@ -36,17 +51,8 @@ export interface 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 {
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: `You are an expert Model Context Protocol (MCP) tool builder.
const systemPrompt = `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.
User Request: "${prompt}"
@@ -75,15 +81,14 @@ Respond ONLY with valid JSON (no markdown ticks or commentary) matching this Typ
"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 parsed = JSON.parse(cleanJson);
return parsed;
} 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);
}
}