GaiaAgentEvaluator / utils /ollama_model.py
davidgturner's picture
- changes for agent
fc78ae4
"""
Alternative model implementation using Ollama API.
This provides a local model implementation that doesn't require PyTorch,
by connecting to a locally running Ollama server.
"""
import logging
import requests
from typing import Dict, List, Optional, Any
from smolagents.models import Model
logger = logging.getLogger(__name__)
class OllamaModel(Model):
"""Model using Ollama API for local inference without PyTorch dependency."""
def __init__(
self,
model_name: str = "llama2",
api_base: str = "http://localhost:11434",
max_tokens: int = 512,
temperature: float = 0.7
):
"""
Initialize a connection to local Ollama server.
Args:
model_name: Ollama model name (e.g., llama2, mistral, gemma)
api_base: Base URL for Ollama API
max_tokens: Maximum new tokens to generate
temperature: Sampling temperature
"""
super().__init__()
try:
self.model_name = model_name
self.api_base = api_base.rstrip('/')
self.max_tokens = max_tokens
self.temperature = temperature
# Test connection to Ollama
print(f"Testing connection to Ollama at {api_base}...")
response = requests.get(f"{self.api_base}/api/tags")
if response.status_code == 200:
models = [model["name"] for model in response.json().get("models", [])]
print(f"Available Ollama models: {models}")
if model_name not in models and models:
print(f"Warning: Model {model_name} not found. Available models: {models}")
print(f"Ollama connection successful")
else:
print(f"Warning: Ollama server not responding correctly. Status code: {response.status_code}")
except Exception as e:
logger.error(f"Error connecting to Ollama: {e}")
print(f"Error connecting to Ollama: {e}")
print("Make sure Ollama is installed and running. Visit https://ollama.ai for installation.")
raise
def generate(self, prompt: str, **kwargs) -> str:
"""
Generate text completion using Ollama API.
Args:
prompt: Input text
Returns:
Generated text completion
"""
try:
print(f"Generating with prompt: {prompt[:50]}...")
# Prepare request
data = {
"model": self.model_name,
"prompt": prompt,
"stream": False,
"options": {
"temperature": self.temperature,
"num_predict": self.max_tokens
}
}
# Make API call
response = requests.post(
f"{self.api_base}/api/generate",
json=data
)
if response.status_code != 200:
error_msg = f"Ollama API error: {response.status_code} - {response.text}"
print(error_msg)
return error_msg
# Extract generated text
result = response.json()
return result.get("response", "No response received")
except Exception as e:
logger.error(f"Error generating text with Ollama: {e}")
print(f"Error generating text with Ollama: {e}")
return f"Error: {str(e)}"
def generate_with_tools(
self,
messages: List[Dict[str, Any]],
tools: Optional[List[Dict[str, Any]]] = None,
**kwargs
) -> Dict[str, Any]:
"""
Generate a response with tool-calling capabilities using Ollama.
Args:
messages: List of message objects with role and content
tools: List of tool definitions
Returns:
Response with message and optional tool calls
"""
try:
# Format messages into a prompt
prompt = self._format_messages_to_prompt(messages, tools)
# Generate response
completion = self.generate(prompt)
# Return the formatted response
return {
"message": {
"role": "assistant",
"content": completion
}
}
except Exception as e:
logger.error(f"Error generating with tools: {e}")
print(f"Error generating with tools: {e}")
return {
"message": {
"role": "assistant",
"content": f"Error: {str(e)}"
}
}
def _format_messages_to_prompt(
self,
messages: List[Dict[str, Any]],
tools: Optional[List[Dict[str, Any]]] = None
) -> str:
"""Format chat messages into a text prompt for the model."""
formatted_prompt = ""
# Include tool descriptions if available
if tools and len(tools) > 0:
tool_descriptions = "\n".join([
f"Tool {i+1}: {tool['name']} - {tool['description']}"
for i, tool in enumerate(tools)
])
formatted_prompt += f"Available tools:\n{tool_descriptions}\n\n"
# Add conversation history
for msg in messages:
role = msg.get("role", "")
content = msg.get("content", "")
if role == "system":
formatted_prompt += f"System: {content}\n\n"
elif role == "user":
formatted_prompt += f"User: {content}\n\n"
elif role == "assistant":
formatted_prompt += f"Assistant: {content}\n\n"
# Add final prompt for assistant
formatted_prompt += "Assistant: "
return formatted_prompt