-
-
Notifications
You must be signed in to change notification settings - Fork 29
feat: Add Ollama integration for local LLM support in Cortex Linux #361
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
base: main
Are you sure you want to change the base?
Changes from all commits
670474c
0c29d7b
1bed948
4679715
b35b693
561c356
9529575
ac68ac3
6d5aeee
a5e9443
498bb94
362b43d
c4d35f1
fe5a528
80b775d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -63,13 +63,15 @@ cortex install "tools for video compression" | |
|
|
||
| | Feature | Description | | ||
| |---------|-------------| | ||
| | **Natural Language** | Describe what you need in plain English | | ||
| | **Dry-Run Default** | Preview all commands before execution | | ||
| | **Sandboxed Execution** | Commands run in Firejail isolation | | ||
| | **Full Rollback** | Undo any installation with `cortex rollback` | | ||
| | **Audit Trail** | Complete history in `~/.cortex/history.db` | | ||
| | **Hardware-Aware** | Detects GPU, CPU, memory for optimized packages | | ||
| | **Multi-LLM Support** | Works with Claude, GPT-4, or local Ollama models | | ||
| | **🤖 Natural Language** | Describe what you need in plain English | | ||
| | **🔒 Privacy-First** | Local LLM support via Ollama - no API keys required | | ||
| | **📴 Offline Capable** | Works completely offline with local models | | ||
| | **🆓 Zero Cost** | Free local inference, optional cloud fallback | | ||
| | **🛡️ Sandboxed Execution** | Commands run in Firejail isolation | | ||
| | **⏮️ Full Rollback** | Undo any installation with `cortex rollback` | | ||
| | **📋 Audit Trail** | Complete history in `~/.cortex/history.db` | | ||
| | **🔧 Hardware-Aware** | Detects GPU, CPU, memory for optimized packages | | ||
| | **☁️ Multi-LLM Support** | Ollama (local), Claude, GPT-4, or Kimi K2 | | ||
|
|
||
| --- | ||
|
|
||
|
|
@@ -79,7 +81,7 @@ cortex install "tools for video compression" | |
|
|
||
| - **OS:** Ubuntu 22.04+ / Debian 12+ | ||
| - **Python:** 3.10 or higher | ||
| - **API Key:** [Anthropic](https://console.anthropic.com) or [OpenAI](https://platform.openai.com) | ||
| - **API Key (Optional):** [Anthropic](https://console.anthropic.com) or [OpenAI](https://platform.openai.com) for cloud fallback | ||
|
|
||
| ### Installation | ||
|
|
||
|
|
@@ -92,24 +94,37 @@ cd cortex | |
| python3 -m venv venv | ||
| source venv/bin/activate | ||
|
|
||
| # 3. Install Cortex | ||
| pip install -e . | ||
| # 3. Upgrade pip and tools | ||
| pip install --upgrade pip setuptools wheel | ||
|
|
||
| # 4. Configure API key | ||
| echo 'ANTHROPIC_API_KEY=your-key-here' > .env | ||
| # 4. Install Cortex with interactive setup | ||
| python setup.py develop | ||
|
|
||
| # During installation, you'll be prompted to install Ollama (local AI) | ||
| # Choose 'y' for offline/private AI, or 'n' to use cloud providers | ||
| ``` | ||
|
Comment on lines
+103
to
+105
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: # First, find and examine the post-install hook file
find . -name "*post_install*" -type f | head -20Repository: cortexlinux/cortex Length of output: 87 🏁 Script executed: # Get the exact content from lines 103-105 of README.md
sed -n '103,105p' README.mdRepository: cortexlinux/cortex Length of output: 205 🏁 Script executed: # Search for the setup.py or installation script to understand the installation flow
find . -name "setup.py" -o -name "setup.cfg" -o -name "pyproject.toml" | head -10Repository: cortexlinux/cortex Length of output: 89 🏁 Script executed: # Search for any Ollama-related prompts or interactive setup code in the codebase
rg -i "ollama.*prompt|prompt.*ollama|you'll be prompted" --type py --type mdRepository: cortexlinux/cortex Length of output: 740 🏁 Script executed: # Examine the post-install hook implementation
cat -n cortex/_post_install.pyRepository: cortexlinux/cortex Length of output: 1805 🏁 Script executed: # Check setup.py to see how post-install is configured
cat setup.pyRepository: cortexlinux/cortex Length of output: 5969 🏁 Script executed: # Examine the first_run_wizard prompt logic
grep -A 10 -B 5 "Install Ollama now" cortex/first_run_wizard.pyRepository: cortexlinux/cortex Length of output: 765 🏁 Script executed: # Search for any issue references or PR discussions about the prompt
rg -i "suyashd|prompt.*doesnt|doesnt.*pop" --type md --type py --type txtRepository: cortexlinux/cortex Length of output: 44 🏁 Script executed: # Examine the setup_ollama function to understand the full flow
cat -n scripts/setup_ollama.py | head -100Repository: cortexlinux/cortex Length of output: 3761 🏁 Script executed: # Check if there are any GitHub issues or PR comments mentioning the prompt issue
git log --all --oneline --grep="ollama\|prompt" | head -20Repository: cortexlinux/cortex Length of output: 373 🏁 Script executed: # Search for recent PRs or issues mentioning Ollama prompt issues
git log --all --oneline | grep -i "PR\|#\|ollama" | head -30Repository: cortexlinux/cortex Length of output: 2164 🏁 Script executed: # Check if there are any discussion files or issue templates
find . -name "*.md" -type f | xargs grep -l "Suyashd999\|ollama prompt" 2>/dev/nullRepository: cortexlinux/cortex Length of output: 46 🏁 Script executed: # Look at the full setup_ollama.py to understand the complete flow
wc -l scripts/setup_ollama.pyRepository: cortexlinux/cortex Length of output: 89 🏁 Script executed: # Check what happens when setup_ollama is called - is there a wizard or direct setup?
grep -n "def setup_ollama\|def _prompt" scripts/setup_ollama.py | head -20Repository: cortexlinux/cortex Length of output: 85 🏁 Script executed: # Read the complete setup_ollama function
sed -n '358,428p' scripts/setup_ollama.pyRepository: cortexlinux/cortex Length of output: 2790 🏁 Script executed: # Check if the wizard is being imported and called
grep -n "import.*wizard\|from.*wizard" scripts/setup_ollama.pyRepository: cortexlinux/cortex Length of output: 44 🏁 Script executed: # Look for any conditional logic that might skip the prompt
grep -n "isatty\|interactive\|TTY\|stdin" scripts/setup_ollama.pyRepository: cortexlinux/cortex Length of output: 242 🏁 Script executed: # Double-check README context around those lines to understand full installation instructions
sed -n '95,115p' README.mdRepository: cortexlinux/cortex Length of output: 578 Document the interactive TTY requirement for Ollama setup prompt. Lines 103-105 promise "you'll be prompted to install Ollama" during Update the documentation to clarify the TTY requirement, or provide explicit instructions for non-interactive setups (e.g., use 🤖 Prompt for AI Agents |
||
|
|
||
| ### Optional: Configure Cloud Providers | ||
|
|
||
| # 5. Verify installation | ||
| cortex --version | ||
| ```bash | ||
| # Only needed if you skipped Ollama or want cloud fallback | ||
| echo 'ANTHROPIC_API_KEY=your-key-here' > .env | ||
| # OR | ||
| echo 'OPENAI_API_KEY=your-key-here' > .env | ||
| ``` | ||
|
|
||
| ### First Run | ||
|
|
||
| ```bash | ||
| # Preview what would be installed (safe, no changes made) | ||
| # Uses local Ollama by default - no API calls! | ||
| cortex install nginx --dry-run | ||
|
|
||
| # Actually install | ||
| cortex install nginx --execute | ||
|
|
||
| # Check Ollama status and installed models | ||
| ollama list | ||
| ``` | ||
|
|
||
| --- | ||
|
|
@@ -119,7 +134,7 @@ cortex install nginx --execute | |
| ### Basic Commands | ||
|
|
||
| ```bash | ||
| # Install with natural language | ||
| # Install with natural language (uses local LLM) | ||
| cortex install "web server for static sites" --dry-run | ||
| cortex install "image editing software like photoshop" --execute | ||
|
|
||
|
|
@@ -131,6 +146,11 @@ cortex rollback <installation-id> | |
|
|
||
| # Check system preferences | ||
| cortex check-pref | ||
|
|
||
| # Manage local LLM models | ||
| ollama list # Show available models | ||
| ollama pull llama3:8b # Download a model | ||
| cortex-setup-ollama # Re-run Ollama setup | ||
| ``` | ||
|
|
||
| ### Command Reference | ||
|
|
@@ -143,6 +163,7 @@ cortex check-pref | |
| | `cortex history` | View all past installations | | ||
| | `cortex rollback <id>` | Undo a specific installation | | ||
| | `cortex check-pref` | Display current preferences | | ||
| | `cortex-setup-ollama` | Setup/reinstall Ollama integration | | ||
| | `cortex --version` | Show version information | | ||
| | `cortex --help` | Display help message | | ||
|
|
||
|
|
@@ -157,6 +178,39 @@ Cortex stores configuration in `~/.cortex/`: | |
| └── audit.log # Detailed audit trail | ||
| ``` | ||
|
|
||
| ### Local LLM Support (Ollama) | ||
|
|
||
| **Privacy-First by Default**: Cortex uses local LLMs via Ollama for zero-cost, offline-capable operation. | ||
|
|
||
| **Benefits:** | ||
| - ✅ **100% Private**: All processing happens locally | ||
| - ✅ **Completely Offline**: Works without internet after setup | ||
| - ✅ **Zero Cost**: No API fees or subscriptions | ||
| - ✅ **No API Keys**: Get started immediately | ||
|
|
||
| **Recommended Models:** | ||
| - `phi3:mini` (1.9GB) - Lightweight, default | ||
| - `llama3:8b` (4.7GB) - Balanced performance | ||
| - `codellama:13b` (9GB) - Code-optimized | ||
| - `deepseek-coder-v2:16b` (10GB+) - Best for system tasks | ||
|
|
||
| **Manage Models:** | ||
| ```bash | ||
| ollama list # Show installed models | ||
| ollama pull llama3:8b # Download a model | ||
| ollama rm phi3:mini # Remove a model | ||
| ``` | ||
|
|
||
| **Cloud Fallback:** | ||
| If local models are unavailable, Cortex automatically falls back to cloud providers (if configured): | ||
| ```bash | ||
| # Optional: Set cloud API keys for fallback | ||
| export ANTHROPIC_API_KEY=your-claude-key | ||
| export OPENAI_API_KEY=your-openai-key | ||
| ``` | ||
|
|
||
| 📖 **[Full Ollama Documentation](docs/OLLAMA_INTEGRATION.md)** | ||
|
|
||
| --- | ||
|
|
||
| ## Architecture | ||
|
|
@@ -176,11 +230,12 @@ Cortex stores configuration in `~/.cortex/`: | |
| ▼ | ||
| ┌─────────────────────────────────────────────────────────────────┐ | ||
| │ LLM Router │ | ||
| │ Claude / GPT-4 / Ollama │ | ||
| │ Ollama (Local) → Claude → GPT-4 → Kimi K2 │ | ||
| │ │ | ||
| │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ | ||
| │ │ Anthropic │ │ OpenAI │ │ Ollama │ │ | ||
| │ │ Claude │ │ GPT-4 │ │ Local │ │ | ||
| │ │ Ollama │ │ Anthropic │ │ OpenAI │ │ | ||
| │ │ (Local) │ │ Claude │ │ GPT-4 │ │ | ||
| │ │ PRIORITY │ │ Fallback 1 │ │ Fallback 2 │ │ | ||
| │ └─────────────┘ └─────────────┘ └─────────────┘ │ | ||
| └─────────────────────────────────────────────────────────────────┘ | ||
| │ | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,51 @@ | ||||||||||
| #!/usr/bin/env python3 | ||||||||||
| """ | ||||||||||
| Post-install hook for Cortex Linux. | ||||||||||
| Automatically runs after pip install to setup Ollama. | ||||||||||
| """ | ||||||||||
|
|
||||||||||
| import os | ||||||||||
| import sys | ||||||||||
|
|
||||||||||
|
|
||||||||||
| def run_setup(): | ||||||||||
| """Run Ollama setup after installation.""" | ||||||||||
|
Comment on lines
+11
to
+12
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major Add missing return type hint. The function 🔎 Proposed fix-def run_setup():
+def run_setup() -> None:
"""Run Ollama setup after installation."""As per coding guidelines, type hints are required in Python code. 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||
| # Skip if in CI or if explicitly disabled | ||||||||||
| if ( | ||||||||||
| os.getenv("CI") | ||||||||||
| or os.getenv("GITHUB_ACTIONS") | ||||||||||
| or os.getenv("CORTEX_SKIP_OLLAMA_SETUP") == "1" | ||||||||||
| ): | ||||||||||
| return | ||||||||||
|
|
||||||||||
| # Check if already ran setup (marker file in user's home) | ||||||||||
| marker_file = os.path.expanduser("~/.cortex/.setup_done") | ||||||||||
| if os.path.exists(marker_file): | ||||||||||
| return | ||||||||||
|
|
||||||||||
| print("\n" + "=" * 70) | ||||||||||
| print("🚀 Running Cortex post-installation setup...") | ||||||||||
| print("=" * 70 + "\n") | ||||||||||
|
|
||||||||||
| try: | ||||||||||
| # Import and run the setup function | ||||||||||
| from scripts.setup_ollama import setup_ollama | ||||||||||
|
|
||||||||||
| setup_ollama() | ||||||||||
|
|
||||||||||
| # Create marker file to prevent running again | ||||||||||
| os.makedirs(os.path.dirname(marker_file), exist_ok=True) | ||||||||||
| with open(marker_file, "w") as f: | ||||||||||
| f.write("Setup completed\n") | ||||||||||
|
|
||||||||||
| except Exception as e: | ||||||||||
| print(f"⚠️ Ollama setup encountered an issue: {e}") | ||||||||||
| print("ℹ️ You can run it manually later with: cortex-setup-ollama") | ||||||||||
| finally: | ||||||||||
| print("\n" + "=" * 70) | ||||||||||
| print("💡 TIP: To re-run setup anytime, execute: cortex-setup-ollama") | ||||||||||
| print("=" * 70) | ||||||||||
|
|
||||||||||
|
|
||||||||||
| if __name__ == "__main__": | ||||||||||
| run_setup() | ||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -372,15 +372,15 @@ def _setup_ollama(self) -> StepResult: | |
| return StepResult(success=True, data={"api_provider": "none"}) | ||
|
|
||
| # Pull a small model | ||
| print("\nPulling llama3.2 model (this may take a few minutes)...") | ||
| print("\nPulling codellama:7b model (this may take a few minutes)...") | ||
| try: | ||
| subprocess.run(["ollama", "pull", "llama3.2"], check=True) | ||
| subprocess.run(["ollama", "pull", "codellama:7b"], check=True) | ||
| print("\n✓ Model ready!") | ||
| except subprocess.CalledProcessError: | ||
| print("\n⚠ Could not pull model - you can do this later with: ollama pull llama3.2") | ||
| print("\n⚠ Could not pull model - you can do this later with: ollama pull codellama:7b") | ||
|
|
||
| self.config["api_provider"] = "ollama" | ||
| self.config["ollama_model"] = "llama3.2" | ||
| self.config["ollama_model"] = "codellama:7b" | ||
|
Comment on lines
+375
to
+383
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Verify default model references across the codebase
echo "=== Checking for codellama:7b references ==="
rg -n "codellama:7b" --type=py --type=md
echo ""
echo "=== Checking for phi3:mini references ==="
rg -n "phi3:mini" --type=py --type=md
echo ""
echo "=== Checking setup_ollama.py for default model ==="
find . -name "setup_ollama.py" -type f | head -5
echo ""
echo "=== Checking ollama_provider.py ==="
find . -name "ollama_provider.py" -type f | head -5Repository: cortexlinux/cortex Length of output: 3407 🏁 Script executed: cat -n cortex/providers/ollama_provider.py | head -80Repository: cortexlinux/cortex Length of output: 2876 🏁 Script executed: sed -n '115,160p' scripts/setup_ollama.pyRepository: cortexlinux/cortex Length of output: 1591 Critical model inconsistency: first_run_wizard.py hardcodes codellama:7b, which is not in OllamaProvider's preferred or fallback models. The first-run wizard unconditionally pulls
This creates a critical integration issue: the wizard pulls a model the provider code doesn't recognize in its preference hierarchy, potentially causing unexpected behavior during model selection fallback logic. Resolution: first_run_wizard.py should either pull from the provider's 🤖 Prompt for AI Agents |
||
|
|
||
| return StepResult(success=True, data={"api_provider": "ollama"}) | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.