-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature/ollama extension #1652
Open
Amiche02
wants to merge
7
commits into
sinaptik-ai:main
Choose a base branch
from
Amiche02:feature/ollama-extension
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Feature/ollama extension #1652
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
bb70d25
ollama extension adding
Amiche02 4c788a4
ollama extension adding
Amiche02 f78b917
premit-checking and readme for ollama integration and usage
Amiche02 9287fc1
premit-checking and readme for ollama integration and usage
Amiche02 b21da05
Update README.md
Amiche02 babd73d
address review feedback and cleanup tests
Amiche02 8bf7387
address review feedback and cleanup tests
Amiche02 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
# PandaAI Ollama LLM Extension | ||
|
||
This extension integrates Ollama language models with PandaAI. It allows you to use Ollama's LLMs as the backend for generating Python code in response to natural language queries on your dataframes. | ||
|
||
## Features | ||
|
||
- **Ollama Integration:** Leverage Ollama's powerful language models (e.g., `llama2`, `llama3.2`) within PandaAI. | ||
- **Customizable Base URL:** Easily change the Ollama base URL (default is `http://localhost:11434/v1`) to point to your own Ollama server. | ||
- **Flexible Model Parameters:** Configure model parameters such as temperature, max tokens, top_p, frequency penalty, etc. | ||
- **Chat & Non-Chat Modes:** Supports both conversational (chat) mode and standard completion mode. | ||
|
||
## Installation | ||
|
||
1. **Clone the Repository** (if you haven't already): | ||
```bash | ||
git clone https://github.com/sinaptik-ai/pandas-ai.git | ||
cd pandas-ai | ||
``` | ||
|
||
2. **Navigate to the Ollama Extension Directory:** | ||
```bash | ||
cd extensions/llms/ollama | ||
``` | ||
|
||
3. **Install the Extension Dependencies:** | ||
```bash | ||
poetry install | ||
|
||
poetry add pandasai-ollama | ||
``` | ||
|
||
> **Note:** If you encounter packaging issues, ensure that this directory contains a valid `README.md` file. This README file is required for Poetry to install the project. | ||
|
||
## Configuration | ||
|
||
### Environment Variables | ||
|
||
You can configure the extension by setting the following environment variables: | ||
|
||
- **`OLLAMA_API_KEY`** | ||
A dummy API key is required by the extension (the key itself is not used). | ||
*Default:* `ollama` | ||
|
||
- **`OLLAMA_BASE_URL`** | ||
Supports a customizable base URL (normalized to end with `/v1`) and flexible model parameters (e.g., temperature, max_tokens).. | ||
*Default format to set:* `http://localhost:11434` | ||
|
||
### Code-Based Configuration | ||
|
||
You can also override configuration options directly in your code when setting up PandaAI: | ||
|
||
```python | ||
import pandasai as pai | ||
from extensions.llms.ollama.pandasai_ollama.ollama import OllamaLLM | ||
|
||
# For Ollama, we use a dummy API key ("ollama") since it isn’t used. | ||
pai.api_key.set("ollama") | ||
|
||
# Set the global configuration to use the Ollama LLM | ||
pai.config.set( | ||
{ | ||
"llm": OllamaLLM( | ||
api_key="ollama", | ||
ollama_base_url="http://localhost:11434", # Custom URL if needed | ||
model="llama3.2:latest", # Specify the model (can be overridden) | ||
temperature=0.7, | ||
max_tokens=150, | ||
) | ||
} | ||
) | ||
``` | ||
|
||
## Usage | ||
|
||
Once you have configured the extension, you can use PandaAI’s DataFrame interface to interact with your data. For example: | ||
|
||
```python | ||
import pandasai as pai | ||
|
||
# Create a sample DataFrame | ||
df = pai.DataFrame({ | ||
"country": ["United States", "United Kingdom", "France", "Germany", "Italy"], | ||
"revenue": [5000, 3200, 2900, 4100, 2300] | ||
}) | ||
|
||
# Ask a natural language question that expects a Python code answer | ||
response = df.chat("Which are the top 5 countries by sales?") | ||
print("Response from Ollama:", response) | ||
``` | ||
|
||
The extension sends your prompt (and any conversation context) to the Ollama LLM backend. The LLM is expected to return a valid Python code snippet that, when executed, produces the desired result. | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
import os | ||
from typing import Any, Dict, Optional | ||
|
||
import openai | ||
|
||
from pandasai.agent.state import AgentState | ||
from pandasai.core.prompts.base import BasePrompt | ||
from pandasai.core.prompts.generate_system_message import GenerateSystemMessagePrompt | ||
from pandasai.helpers import load_dotenv | ||
from pandasai.llm.base import LLM | ||
|
||
# Load .env if present | ||
load_dotenv() | ||
|
||
|
||
class OllamaLLM(LLM): | ||
_type: str = "ollama" | ||
model: str = "llama2" # default model, can be overridden | ||
|
||
def __init__( | ||
self, | ||
api_key: Optional[str] = None, | ||
ollama_base_url: Optional[str] = None, | ||
**kwargs: Any, | ||
) -> None: | ||
# For Ollama, a dummy API key is required (but not used) | ||
self.api_key = api_key or os.getenv("OLLAMA_API_KEY", "ollama") | ||
# Get base URL from parameter or env, default to localhost | ||
base = ollama_base_url or os.getenv("OLLAMA_BASE_URL", "http://localhost:11434") | ||
# Ensure the base URL ends with "/v1" | ||
if not base.rstrip("/").endswith("/v1"): | ||
base = base.rstrip("/") + "/v1" | ||
self.base_url = base | ||
|
||
# Set additional parameters (e.g. model, temperature, etc.) | ||
self._set_params(**kwargs) | ||
|
||
# Assume chat mode by default | ||
self._is_chat_model = True | ||
self.client = openai.OpenAI( | ||
api_key=self.api_key, | ||
base_url=self.base_url, | ||
**self._client_params, | ||
).chat.completions | ||
|
||
def _set_params(self, **kwargs: Any) -> None: | ||
valid_params = [ | ||
"model", | ||
"temperature", | ||
"max_tokens", | ||
"top_p", | ||
"frequency_penalty", | ||
"presence_penalty", | ||
"stop", | ||
"n", | ||
"best_of", | ||
"request_timeout", | ||
"max_retries", | ||
"seed", | ||
] | ||
for key, value in kwargs.items(): | ||
if key in valid_params: | ||
setattr(self, key, value) | ||
|
||
@property | ||
def _client_params(self) -> Dict[str, Any]: | ||
return { | ||
"timeout": getattr(self, "request_timeout", None), | ||
"max_retries": getattr(self, "max_retries", 2), | ||
} | ||
|
||
@property | ||
def _default_params(self) -> Dict[str, Any]: | ||
params: Dict[str, Any] = { | ||
"temperature": getattr(self, "temperature", 0), | ||
"top_p": getattr(self, "top_p", 1), | ||
"frequency_penalty": getattr(self, "frequency_penalty", 0), | ||
"presence_penalty": getattr(self, "presence_penalty", 0), | ||
"n": getattr(self, "n", 1), | ||
} | ||
if hasattr(self, "max_tokens") and self.max_tokens is not None: | ||
params["max_tokens"] = self.max_tokens | ||
if hasattr(self, "stop") and self.stop is not None: | ||
params["stop"] = [self.stop] | ||
if hasattr(self, "best_of") and self.best_of > 1: | ||
params["best_of"] = self.best_of | ||
return params | ||
|
||
def call(self, instruction: BasePrompt, context: AgentState = None) -> str: | ||
# Get the base prompt string from the user instruction. | ||
prompt_str = instruction.to_string() | ||
# If a context is provided with conversation memory, | ||
# prepend the system prompt (generated via GenerateSystemMessagePrompt). | ||
if context and context.memory: | ||
system_prompt = GenerateSystemMessagePrompt(memory=context.memory) | ||
prompt_str = system_prompt.to_string() + "\n" + prompt_str | ||
|
||
if self._is_chat_model: | ||
response = self.client.create( | ||
model=self.model, | ||
messages=[{"role": "user", "content": prompt_str}], | ||
**self._default_params, | ||
) | ||
return response.choices[0].message.content | ||
else: | ||
response = self.client.create( | ||
model=self.model, | ||
prompt=prompt_str, | ||
**self._default_params, | ||
) | ||
return response.choices[0].text | ||
|
||
@property | ||
def type(self) -> str: | ||
return self._type |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is an inconsistency in the spelling of the project name between the title and the text. The title uses "PandasAI" while the text in line 3 and later sections refers to "PandaAI". For clarity and consistency, please standardize the naming to one consistent form.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you,I will take all that in account, and correct the issues
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Changes Description: