import { Router } from "express"; import { getSession, addMessage } from "../services/sessionStore.js"; import { getOllamaModel, buildLangChainMessages, aiMessageToClaudeResponse } from "../services/langchainModels.js"; const router = Router(); router.post("/*path", async (req, res) => { const requestStart = Date.now(); console.log(`[Ollama API] ========== REQUEST START ==========`); const { sessionId, model: modelId, max_tokens, system: systemPrompt, messages } = req.body; console.log(`[Ollama API] Session ID: ${sessionId || 'none'}`); console.log(`[Ollama API] Model: ${modelId}`); console.log(`[Ollama API] Messages count: ${messages?.length || 0}`); try { // Get LangChain model with tools bound const model = getOllamaModel(modelId); // Build messages with entity context and history const langChainMessages = buildLangChainMessages( sessionId, messages, systemPrompt ); console.log(`[Ollama API] Sending request via LangChain...`); const fetchStart = Date.now(); // Invoke model const response = await model.invoke(langChainMessages); const fetchDuration = Date.now() - fetchStart; console.log(`[Ollama API] Response received in ${fetchDuration}ms`); // Convert to Claude API format for client compatibility const claudeResponse = aiMessageToClaudeResponse(response, modelId); console.log(`[Ollama API] Response converted. Stop reason: ${claudeResponse.stop_reason}, content blocks: ${claudeResponse.content.length}`); // Store messages to session if applicable if (sessionId && claudeResponse.content) { const session = getSession(sessionId); if (session) { const userMessage = messages?.[messages.length - 1]; if (userMessage && userMessage.role === 'user' && typeof userMessage.content === 'string') { addMessage(sessionId, { role: 'user', content: userMessage.content }); console.log(`[Ollama API] Stored user message to session`); } const assistantContent = claudeResponse.content .filter(c => c.type === 'text') .map(c => c.text) .join('\n'); if (assistantContent) { addMessage(sessionId, { role: 'assistant', content: assistantContent }); console.log(`[Ollama API] Stored assistant response to session (${assistantContent.length} chars)`); } } } const totalDuration = Date.now() - requestStart; console.log(`[Ollama API] ========== REQUEST COMPLETE (${totalDuration}ms) ==========`); res.json(claudeResponse); } catch (error) { const totalDuration = Date.now() - requestStart; console.error(`[Ollama API] ========== REQUEST FAILED (${totalDuration}ms) ==========`); console.error(`[Ollama API] Error:`, error); // Check if it's a connection error if (error.cause?.code === 'ECONNREFUSED' || error.message?.includes('ECONNREFUSED')) { return res.status(503).json({ error: "Ollama is not running", details: `Could not connect to Ollama. Make sure Ollama is installed and running.` }); } res.status(500).json({ error: "Failed to call Ollama", details: error.message }); } }); export default router;