diff --git a/README.md b/README.md index 3748743..17154d6 100644 --- a/README.md +++ b/README.md @@ -24,13 +24,13 @@ Checkout our website ยป

- ๐Ÿ“š Get Started + ๐Ÿ“š Get Started ยท - ๐Ÿ“– User Guide + ๐Ÿ“– User Guide ยท - โœจ Features + โœจ Features ยท - ๐Ÿš€ Deploy + ๐Ÿš€ Deploy

@@ -75,13 +75,12 @@ Learn more about our project at [https://www.open-notebook.ai](https://www.open- | **Privacy & Control** | Self-hosted, your data | Google cloud only | Complete data sovereignty | | **AI Provider Choice** | 16+ providers (OpenAI, Anthropic, Ollama, LM Studio, etc.) | Google models only | Flexibility and cost optimization | | **Podcast Speakers** | 1-4 speakers with custom profiles | 2 speakers only | Extreme flexibility | -| **Context Control** | 3 granular levels | All-or-nothing | Privacy and performance tuning | | **Content Transformations** | Custom and built-in | Limited options | Unlimited processing power | | **API Access** | Full REST API | No API | Complete automation | | **Deployment** | Docker, cloud, or local | Google hosted only | Deploy anywhere | -| **Citations** | Comprehensive with sources | Basic references | Research integrity | +| **Citations** | Basic references (will improve) | Comprehensive with sources | Research integrity | | **Customization** | Open source, fully customizable | Closed system | Unlimited extensibility | -| **Cost** | Pay only for AI usage | Monthly subscription + usage | Transparent and controllable | +| **Cost** | Pay only for AI usage | Free tier + Monthly subscription | Transparent and controllable | **Why Choose Open Notebook?** - ๐Ÿ”’ **Privacy First**: Your sensitive research stays completely private @@ -96,181 +95,58 @@ Learn more about our project at [https://www.open-notebook.ai](https://www.open- ## ๐Ÿš€ Quick Start -**Docker Images Available:** -- **Docker Hub**: `lfnovo/open_notebook:v1-latest-single` -- **GitHub Container Registry**: `ghcr.io/lfnovo/open-notebook:v1-latest-single` +Choose your installation method: -Both registries contain identical images - choose whichever you prefer! +### ๐Ÿณ **Docker (Recommended)** -### Choose Your Setup: +**Best for most users** - Fast setup with Docker Compose: - - - - - -
+โ†’ **[Docker Compose Installation Guide](docs/1-INSTALLATION/docker-compose.md)** +- Multi-container setup (recommended) +- 5-10 minutes setup time +- Requires Docker Desktop -#### ๐Ÿ  **Local Machine Setup** -Perfect if Docker runs on the **same computer** where you'll access Open Notebook. +**Quick Start:** +- Get an API key (OpenAI, Anthropic, Google, etc.) or setup Ollama +- Create docker-compose.yml (example in guide) +- Run: docker compose up -d +- Access: http://localhost:8502 +--- + +### ๐Ÿ’ป **From Source (Developers)** + +**For development and contributors:** + +โ†’ **[From Source Installation Guide](docs/1-INSTALLATION/from-source.md)** +- Clone and run locally +- 10-15 minutes setup time +- Requires: Python 3.11+, Node.js 18+, Docker, uv + +**Quick Start:** ```bash -mkdir open-notebook && cd open-notebook - -docker run -d \ - --name open-notebook \ - -p 8502:8502 -p 5055:5055 \ - -v ./notebook_data:/app/data \ - -v ./surreal_data:/mydata \ - -e OPENAI_API_KEY=your_key_here \ - -e SURREAL_URL="ws://localhost:8000/rpc" \ - -e SURREAL_USER="root" \ - -e SURREAL_PASSWORD="root" \ - -e SURREAL_NAMESPACE="open_notebook" \ - -e SURREAL_DATABASE="open_notebook" \ - lfnovo/open_notebook:v1-latest-single +git clone https://github.com/lfnovo/open-notebook.git +uv sync +make start-all ``` -**Access at:** http://localhost:8502 +Access: http://localhost:3000 (dev) or http://localhost:8502 (production) - +--- -#### ๐ŸŒ **Remote Server Setup** -Use this for servers, Raspberry Pi, NAS, Proxmox, or any remote machine. +### ๐Ÿ“– Need Help? -```bash -mkdir open-notebook && cd open-notebook +- **๐Ÿค– AI Installation Assistant**: [CustomGPT to help you install](https://chatgpt.com/g/g-68776e2765b48191bd1bae3f30212631-open-notebook-installation-assistant) +- **๐Ÿ†˜ Troubleshooting**: [5-minute troubleshooting guide](docs/6-TROUBLESHOOTING/quick-fixes.md) +- **๐Ÿ’ฌ Community Support**: [Discord Server](https://discord.gg/37XJPXfz2w) +- **๐Ÿ› Report Issues**: [GitHub Issues](https://github.com/lfnovo/open-notebook/issues) -docker run -d \ - --name open-notebook \ - -p 8502:8502 -p 5055:5055 \ - -v ./notebook_data:/app/data \ - -v ./surreal_data:/mydata \ - -e OPENAI_API_KEY=your_key_here \ - -e API_URL=http://YOUR_SERVER_IP:5055 \ - -e SURREAL_URL="ws://localhost:8000/rpc" \ - -e SURREAL_USER="root" \ - -e SURREAL_PASSWORD="root" \ - -e SURREAL_NAMESPACE="open_notebook" \ - -e SURREAL_DATABASE="open_notebook" \ - lfnovo/open_notebook:v1-latest-single -``` - -**Replace `YOUR_SERVER_IP`** with your server's IP (e.g., `192.168.1.100`) or domain - -**Access at:** http://YOUR_SERVER_IP:8502 - -
- -> **โš ๏ธ Critical Setup Notes:** -> -> **Both ports are required:** -> - **Port 8502**: Web interface (what you see in your browser) -> - **Port 5055**: API backend (required for the app to function) -> -> **API_URL must match how YOU access the server:** -> - โœ… Access via `http://192.168.1.100:8502` โ†’ set `API_URL=http://192.168.1.100:5055` -> - โœ… Access via `http://myserver.local:8502` โ†’ set `API_URL=http://myserver.local:5055` -> - โŒ Don't use `localhost` for remote servers - it won't work from other devices! - -### Using Docker Compose (Recommended for Easy Management) - -Create a `docker-compose.yml` file: - -```yaml -services: - open_notebook: - image: lfnovo/open_notebook:v1-latest-single - # Or use: ghcr.io/lfnovo/open-notebook:v1-latest-single - ports: - - "8502:8502" # Web UI - - "5055:5055" # API (required!) - environment: - - OPENAI_API_KEY=your_key_here - # For remote access, uncomment and set your server IP/domain: - # - API_URL=http://192.168.1.100:5055 - # Database connection (required for single-container) - - SURREAL_URL=ws://localhost:8000/rpc - - SURREAL_USER=root - - SURREAL_PASSWORD=root - - SURREAL_NAMESPACE=open_notebook - - SURREAL_DATABASE=open_notebook - volumes: - - ./notebook_data:/app/data - - ./surreal_data:/mydata - restart: always -``` - -Start with: `docker compose up -d` - -**What gets created:** -``` -open-notebook/ -โ”œโ”€โ”€ docker-compose.yml # Your configuration -โ”œโ”€โ”€ notebook_data/ # Your notebooks and research content -โ””โ”€โ”€ surreal_data/ # Database files -``` - -### ๐Ÿ†˜ Quick Troubleshooting - -| Problem | Solution | -|---------|----------| -| **"Unable to connect to server"** | Set `API_URL` environment variable to match how you access the server (see remote setup above) | -| **Blank page or errors** | Ensure BOTH ports (8502 and 5055) are exposed in your docker command | -| **Works on server but not from other computers** | Don't use `localhost` in `API_URL` - use your server's actual IP address | -| **"404" or "config endpoint" errors** | Don't add `/api` to `API_URL` - use just `http://your-ip:5055` | -| **Still having issues?** | Check our [5-minute troubleshooting guide](docs/troubleshooting/quick-fixes.md) or [join Discord](https://discord.gg/37XJPXfz2w) | - -### How Open Notebook Works - -``` -โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” -โ”‚ Your Browser โ”‚ -โ”‚ Access: http://your-server-ip:8502 โ”‚ -โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ - โ”‚ - โ–ผ - โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” - โ”‚ Port 8502 โ”‚ โ† Next.js Frontend (what you see) - โ”‚ Frontend โ”‚ Also proxies API requests internally! - โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ - โ”‚ proxies /api/* requests โ†“ - โ–ผ - โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” - โ”‚ Port 5055 โ”‚ โ† FastAPI Backend (handles requests) - โ”‚ API โ”‚ - โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ - โ”‚ - โ–ผ - โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” - โ”‚ SurrealDB โ”‚ โ† Database (internal, auto-configured) - โ”‚ (Port 8000) โ”‚ - โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ -``` - -**Key Points:** -- **v1.1+**: Next.js automatically proxies `/api/*` requests to the backend, simplifying reverse proxy setup -- Your browser loads the frontend from port 8502 -- The frontend needs to know where to find the API - when accessing remotely, set: `API_URL=http://your-server-ip:5055` -- **Behind reverse proxy?** You only need to proxy to port 8502 now! See [Reverse Proxy Guide](docs/deployment/reverse-proxy.md) +--- ## Star History [![Star History Chart](https://api.star-history.com/svg?repos=lfnovo/open-notebook&type=date&legend=top-left)](https://www.star-history.com/#lfnovo/open-notebook&type=date&legend=top-left) -### ๐Ÿ› ๏ธ Full Installation -For development or customization: -```bash -git clone https://github.com/lfnovo/open-notebook -cd open-notebook -make start-all -``` - -### ๐Ÿ“– Need Help? -- **๐Ÿค– AI Installation Assistant**: We have a [CustomGPT built to help you install Open Notebook](https://chatgpt.com/g/g-68776e2765b48191bd1bae3f30212631-open-notebook-installation-assistant) - it will guide you through each step! -- **New to Open Notebook?** Start with our [Getting Started Guide](docs/getting-started/index.md) -- **Need installation help?** Check our [Installation Guide](docs/getting-started/installation.md) -- **Want to see it in action?** Try our [Quick Start Tutorial](docs/getting-started/quick-start.md) ## Provider Support Matrix @@ -316,36 +192,47 @@ Thanks to the [Esperanto](https://github.com/lfnovo/esperanto) library, we suppo - **๐Ÿ“Š Fine-Grained Context Control**: Choose exactly what to share with AI models - **๐Ÿ“Ž Citations**: Get answers with proper source citations -### Three-Column Interface -1. **Sources**: Manage all your research materials -2. **Notes**: Create manual or AI-generated notes -3. **Chat**: Converse with AI using your content as context + +## Podcast Feature + +### Audio 1 + + +### Audio 2 + + [![Check out our podcast sample](https://img.youtube.com/vi/D-760MlGwaI/0.jpg)](https://www.youtube.com/watch?v=D-760MlGwaI) ## ๐Ÿ“š Documentation ### Getting Started -- **[๐Ÿ“– Introduction](docs/getting-started/introduction.md)** - Learn what Open Notebook offers -- **[โšก Quick Start](docs/getting-started/quick-start.md)** - Get up and running in 5 minutes -- **[๐Ÿ”ง Installation](docs/getting-started/installation.md)** - Comprehensive setup guide -- **[๐ŸŽฏ Your First Notebook](docs/getting-started/first-notebook.md)** - Step-by-step tutorial +- **[๐Ÿ“– Introduction](docs/0-START-HERE/index.md)** - Learn what Open Notebook offers +- **[โšก Quick Start](docs/0-START-HERE/quick-start.md)** - Get up and running in 5 minutes +- **[๐Ÿ”ง Installation](docs/1-INSTALLATION/index.md)** - Comprehensive setup guide +- **[๐ŸŽฏ Your First Notebook](docs/0-START-HERE/first-notebook.md)** - Step-by-step tutorial ### User Guide -- **[๐Ÿ“ฑ Interface Overview](docs/user-guide/interface-overview.md)** - Understanding the layout -- **[๐Ÿ“š Notebooks](docs/user-guide/notebooks.md)** - Organizing your research -- **[๐Ÿ“„ Sources](docs/user-guide/sources.md)** - Managing content types -- **[๐Ÿ“ Notes](docs/user-guide/notes.md)** - Creating and managing notes -- **[๐Ÿ’ฌ Chat](docs/user-guide/chat.md)** - AI conversations -- **[๐Ÿ” Search](docs/user-guide/search.md)** - Finding information +- **[๐Ÿ“ฑ Interface Overview](docs/3-USER-GUIDE/interface-overview.md)** - Understanding the layout +- **[๐Ÿ“š Notebooks](docs/3-USER-GUIDE/notebooks.md)** - Organizing your research +- **[๐Ÿ“„ Sources](docs/3-USER-GUIDE/sources.md)** - Managing content types +- **[๐Ÿ“ Notes](docs/3-USER-GUIDE/notes.md)** - Creating and managing notes +- **[๐Ÿ’ฌ Chat](docs/3-USER-GUIDE/chat.md)** - AI conversations +- **[๐Ÿ” Search](docs/3-USER-GUIDE/search.md)** - Finding information ### Advanced Topics -- **[๐ŸŽ™๏ธ Podcast Generation](docs/features/podcasts.md)** - Create professional podcasts -- **[๐Ÿ”ง Content Transformations](docs/features/transformations.md)** - Customize content processing -- **[๐Ÿค– AI Models](docs/features/ai-models.md)** - AI model configuration -- **[๐Ÿ”ง REST API Reference](docs/development/api-reference.md)** - Complete API documentation -- **[๐Ÿ” Security](docs/deployment/security.md)** - Password protection and privacy -- **[๐Ÿš€ Deployment](docs/deployment/index.md)** - Complete deployment guides for all scenarios +- **[๐ŸŽ™๏ธ Podcast Generation](docs/2-CORE-CONCEPTS/podcasts.md)** - Create professional podcasts +- **[๐Ÿ”ง Content Transformations](docs/2-CORE-CONCEPTS/transformations.md)** - Customize content processing +- **[๐Ÿค– AI Models](docs/4-AI-PROVIDERS/index.md)** - AI model configuration +- **[๐Ÿ”ง REST API Reference](docs/7-DEVELOPMENT/api-reference.md)** - Complete API documentation +- **[๐Ÿ” Security](docs/5-CONFIGURATION/security.md)** - Password protection and privacy +- **[๐Ÿš€ Deployment](docs/1-INSTALLATION/index.md)** - Complete deployment guides for all scenarios

(back to top)

@@ -371,6 +258,12 @@ See the [open issues](https://github.com/lfnovo/open-notebook/issues) for a full

(back to top)

+## ๐Ÿ“– Need Help? +- **๐Ÿค– AI Installation Assistant**: We have a [CustomGPT built to help you install Open Notebook](https://chatgpt.com/g/g-68776e2765b48191bd1bae3f30212631-open-notebook-installation-assistant) - it will guide you through each step! +- **New to Open Notebook?** Start with our [Getting Started Guide](docs/0-START-HERE/index.md) +- **Need installation help?** Check our [Installation Guide](docs/1-INSTALLATION/index.md) +- **Want to see it in action?** Try our [Quick Start Tutorial](docs/0-START-HERE/quick-start.md) + ## ๐Ÿค Community & Contributing ### Join the Community @@ -397,25 +290,12 @@ See our [Contributing Guide](CONTRIBUTING.md) for detailed information on how to Open Notebook is MIT licensed. See the [LICENSE](LICENSE) file for details. -## ๐Ÿ“ž Contact - -**Luis Novo** - [@lfnovo](https://twitter.com/lfnovo) **Community Support**: - ๐Ÿ’ฌ [Discord Server](https://discord.gg/37XJPXfz2w) - Get help, share ideas, and connect with users - ๐Ÿ› [GitHub Issues](https://github.com/lfnovo/open-notebook/issues) - Report bugs and request features - ๐ŸŒ [Website](https://www.open-notebook.ai) - Learn more about the project -## ๐Ÿ™ Acknowledgments - -Open Notebook is built on the shoulders of amazing open-source projects: - -* **[Podcast Creator](https://github.com/lfnovo/podcast-creator)** - Advanced podcast generation capabilities -* **[Surreal Commands](https://github.com/lfnovo/surreal-commands)** - Background job processing -* **[Content Core](https://github.com/lfnovo/content-core)** - Content processing and management -* **[Esperanto](https://github.com/lfnovo/esperanto)** - Multi-provider AI model abstraction -* **[Docling](https://github.com/docling-project/docling)** - Document processing and parsing -

(back to top)

diff --git a/docs/4-AI-PROVIDERS/index.md b/docs/4-AI-PROVIDERS/index.md index e5decd5..c291832 100644 --- a/docs/4-AI-PROVIDERS/index.md +++ b/docs/4-AI-PROVIDERS/index.md @@ -1,6 +1,8 @@ -# AI Providers - Setup & Configuration +# AI Providers - Comparison & Selection Guide -Open Notebook supports 15+ AI providers. This section helps you choose and configure yours. +Open Notebook supports 15+ AI providers. This guide helps you **choose the right provider** for your needs. + +> ๐Ÿ’ก **Just want to set up a provider?** Skip to the [Configuration Guide](../5-CONFIGURATION/ai-providers.md) for detailed setup instructions. --- @@ -9,72 +11,67 @@ Open Notebook supports 15+ AI providers. This section helps you choose and confi ### Cloud Providers (Easiest) **OpenAI (Recommended)** -- Models: GPT-4o, GPT-4o-mini - Cost: ~$0.03-0.15 per 1K tokens - Speed: Very fast -- Setup: 5 minutes +- Quality: Excellent - Best for: Most users (best quality/price balance) โ†’ [Setup Guide](../5-CONFIGURATION/ai-providers.md#openai) **Anthropic (Claude)** -- Models: Claude 3.5 Sonnet, Haiku, Opus - Cost: ~$0.80-3.00 per 1M tokens - Speed: Fast -- Setup: 5 minutes -- Best for: Long context, reasoning -- Advantage: 200K token context +- Quality: Excellent +- Best for: Long context (200K tokens), reasoning, latest AI +- Advantage: Superior long-context handling โ†’ [Setup Guide](../5-CONFIGURATION/ai-providers.md#anthropic-claude) **Google Gemini** -- Models: Gemini 2.0 Flash, 1.5 Pro - Cost: ~$0.075-0.30 per 1K tokens - Speed: Very fast -- Setup: 5 minutes +- Quality: Good to excellent - Best for: Multimodal (images, audio, video) -- Advantage: 1M token context +- Advantage: Longest context (up to 2M tokens) โ†’ [Setup Guide](../5-CONFIGURATION/ai-providers.md#google-gemini) **Groq (Ultra-Fast)** -- Models: Mixtral, Llama 3.3 - Cost: ~$0.05 per 1M tokens (cheapest) - Speed: Ultra-fast (fastest available) -- Setup: 5 minutes -- Best for: Budget-conscious, transformations +- Quality: Good +- Best for: Budget-conscious, transformations, speed-critical tasks - Disadvantage: Limited model selection โ†’ [Setup Guide](../5-CONFIGURATION/ai-providers.md#groq) **OpenRouter (100+ Models)** -- Models: Access to OpenAI, Anthropic, Google, Llama, Mistral, and 100+ more -- Cost: Pay-per-model (varies) +- Cost: Pay-per-model (varies widely) - Speed: Varies by model -- Setup: 5 minutes -- Best for: Model comparison, testing many models, unified billing -- Advantage: One API key for all models +- Quality: Varies by model +- Best for: Model comparison, testing, unified billing +- Advantage: One API key for 100+ models from different providers โ†’ [Setup Guide](../5-CONFIGURATION/ai-providers.md#openrouter) ### Local / Self-Hosted (Free) **Ollama (Recommended for Local)** -- Models: Mistral, Llama 2, Phi, Neural Chat - Cost: Free (electricity only) - Speed: Depends on hardware (slow on CPU, fast on GPU) +- Quality: Good (open-source models) - Setup: 10 minutes - Best for: Privacy-first, offline use - Privacy: 100% local, nothing leaves your machine -โ†’ [Setup Guide](../5-CONFIGURATION/ai-providers.md#ollama-local) +โ†’ [Setup Guide](../5-CONFIGURATION/ai-providers.md#ollama-recommended-for-local) **LM Studio (Alternative)** -- GUI-based local LLM runner -- Cost: Free +- Cost: Free (electricity only) - Speed: Depends on hardware -- Setup: 15 minutes (GUI easier than Ollama CLI) -- Best for: Non-technical users +- Quality: Good (same models as Ollama) +- Setup: 15 minutes (GUI interface) +- Best for: Non-technical users who prefer GUI over CLI - Privacy: 100% local โ†’ [Setup Guide](../5-CONFIGURATION/ai-providers.md#lm-studio-local-alternative) @@ -82,10 +79,11 @@ Open Notebook supports 15+ AI providers. This section helps you choose and confi ### Enterprise **Azure OpenAI** -- Same as OpenAI but on Azure -- Cost: Same as OpenAI +- Cost: Same as OpenAI (usage-based) +- Speed: Very fast +- Quality: Excellent (same models as OpenAI) - Setup: 10 minutes (more complex) -- Best for: Enterprise, compliance (HIPAA, SOC2) +- Best for: Enterprise, compliance (HIPAA, SOC2), VPC integration โ†’ [Setup Guide](../5-CONFIGURATION/ai-providers.md#azure-openai) @@ -93,16 +91,16 @@ Open Notebook supports 15+ AI providers. This section helps you choose and confi ## Comparison Table -| Provider | Speed | Cost | Quality | Privacy | Setup | Models | -|----------|-------|------|---------|---------|-------|--------| -| **OpenAI** | Very Fast | $$ | Excellent | Low | 5 min | Many | -| **Anthropic** | Fast | $$ | Excellent | Low | 5 min | Few | -| **Google** | Very Fast | $$ | Good | Low | 5 min | Few | -| **Groq** | Ultra Fast | $ | Good | Low | 5 min | Few | -| **OpenRouter** | Varies | Varies | Varies | Low | 5 min | 100+ | -| **Ollama** | Slow-Medium | Free | Good | Max | 10 min | Many | -| **LM Studio** | Slow-Medium | Free | Good | Max | 15 min | Many | -| **Azure** | Very Fast | $$ | Excellent | High | 10 min | Many | +| Provider | Speed | Cost | Quality | Privacy | Setup | Context | +|----------|-------|------|---------|---------|-------|---------| +| **OpenAI** | Very Fast | $$ | Excellent | Low | 5 min | 128K | +| **Anthropic** | Fast | $$ | Excellent | Low | 5 min | 200K | +| **Google** | Very Fast | $$ | Good-Excellent | Low | 5 min | 2M | +| **Groq** | Ultra Fast | $ | Good | Low | 5 min | 32K | +| **OpenRouter** | Varies | Varies | Varies | Low | 5 min | Varies | +| **Ollama** | Slow-Medium | Free | Good | Max | 10 min | Varies | +| **LM Studio** | Slow-Medium | Free | Good | Max | 15 min | Varies | +| **Azure** | Very Fast | $$ | Excellent | High | 10 min | 128K | --- @@ -137,117 +135,19 @@ Open Notebook supports 15+ AI providers. This section helps you choose and confi --- -## Setup Paths +## Ready to Set Up Your Provider? -### Path 1: OpenAI (Most Common) +Now that you've chosen a provider, follow the detailed setup instructions: -``` -1. Go to https://platform.openai.com/api-keys -2. Create account, add $5+ credit -3. Create API key -4. Add to .env: OPENAI_API_KEY=sk-... -5. Restart services -6. Done! -``` +โ†’ **[AI Providers Configuration Guide](../5-CONFIGURATION/ai-providers.md)** -**Time:** 5 minutes -**Cost:** Pay as you go (~$1-5/month light use) - -### Path 2: Local Ollama (Privacy) - -``` -1. Download Ollama: https://ollama.ai -2. Run: ollama serve -3. Download model: ollama pull mistral -4. Add to .env: OLLAMA_API_BASE=http://localhost:11434 -5. Restart services -6. Done! -``` - -**Time:** 10 minutes -**Cost:** Free (electricity only) -**Requirement:** 8GB RAM minimum (16GB+ recommended) - -### Path 3: Anthropic (Better Reasoning) - -``` -1. Go to https://console.anthropic.com/ -2. Create account, add payment method -3. Create API key -4. Add to .env: ANTHROPIC_API_KEY=sk-ant-... -5. Restart services -6. Done! -``` - -**Time:** 5 minutes -**Cost:** Pay as you go (~$2-20/month typical use) - -### Path 4: OpenRouter (100+ Models) - -``` -1. Go to https://openrouter.ai/keys -2. Create account, add credit -3. Create API key -4. Add to .env: OPENROUTER_API_KEY=sk-or-... -5. Restart services -6. Done! -``` - -**Time:** 5 minutes -**Cost:** Varies by model ($0.05-15 per 1M tokens) - ---- - -## Model Recommendations by Task - -### General Chat -- OpenAI: `gpt-4o` (best) or `gpt-4o-mini` (cheap) -- Anthropic: `claude-3-5-sonnet` (best) -- Google: `gemini-2.0-flash` (balanced) -- Groq: `mixtral-8x7b-32768` (fast) -- Ollama: `mistral` (balanced) - -### Long Documents (200K+ tokens) -- Anthropic: `claude-3-5-sonnet` (200K context) -- Google: `gemini-1.5-pro` (1M context) -- OpenAI: `gpt-4-turbo` (128K context) - -### Fast/Cheap Operations -- Groq: Ultra-fast, very cheap -- OpenAI: `gpt-4o-mini` (fast, cheap) -- Anthropic: `claude-3-5-haiku` (cheap) - -### Multimodal (Images/Audio/Video) -- Google: `gemini-2.0-flash` (best multimodal) -- OpenAI: `gpt-4o` (good multimodal) - -### Local/Offline -- Ollama: `mistral` (best local balance) -- LM Studio: `mistral` or `llama2` - ---- - -## Complete Configuration Reference - -For detailed environment variable setup, see: -โ†’ [Complete Configuration Reference](../5-CONFIGURATION/environment-reference.md) - -For detailed AI provider configuration, see: -โ†’ [AI Providers Configuration](../5-CONFIGURATION/ai-providers.md) - ---- - -## Testing Your Setup - -Once configured: - -``` -1. Start Open Notebook -2. Go to Settings โ†’ Models -3. Select your configured provider -4. Try a Chat question -5. If it responds, you're good! -``` +This guide includes: +- Step-by-step setup instructions for each provider +- Environment variable configuration +- Model selection and recommendations +- Provider-specific troubleshooting +- Hardware requirements (for local providers) +- Cost optimization tips --- @@ -282,81 +182,18 @@ Any use: Free (electricity only) --- -## Switching Providers - -You can switch providers anytime: - -``` -1. Edit .env -2. Change/add API key -3. Restart services -4. Go to Settings โ†’ Models -5. Select new provider -6. Done! -``` - -Your existing notebooks and data stay the same. - ---- - -## Provider-Specific Guides - -For detailed setup instructions per provider, see: -โ†’ [5-CONFIGURATION/ai-providers.md](../5-CONFIGURATION/ai-providers.md) - -Includes: -- OpenAI -- Anthropic -- Google Gemini -- Groq -- OpenRouter -- Mistral -- DeepSeek -- xAI -- Ollama -- LM Studio -- OpenAI-Compatible -- Azure OpenAI - ---- - -## Troubleshooting - -**"Models not showing in Settings"** -- API key missing or wrong -- Restart services after changing .env -- Check the key is set correctly: `echo $OPENAI_API_KEY` - -**"API key invalid"** -- Copy fresh key from provider's dashboard -- Check no extra spaces: `OPENAI_API_KEY="sk-..."` -- Verify key format matches provider - -**"Rate limit exceeded"** -- You're hitting provider's rate limits -- Wait a bit, retry -- For cloud: upgrade account or reduce request rate - -**"Connection refused" (Ollama)** -- Ollama not running: `ollama serve` -- Wrong port: Check `OLLAMA_API_BASE` -- Not on localhost: Use IP instead - ---- - ## Next Steps -1. **Pick a provider** from above -2. **Follow setup guide** in [5-CONFIGURATION/ai-providers.md](../5-CONFIGURATION/ai-providers.md) -3. **Add API key** to .env -4. **Restart services** -5. **Test in Settings โ†’ Models** -6. **Start using!** +1. โœ… **You've chosen a provider** (from this comparison guide) +2. ๐Ÿ“– **Follow the setup guide**: [AI Providers Configuration](../5-CONFIGURATION/ai-providers.md) +3. โš™๏ธ **Configure your environment** (detailed in the setup guide) +4. ๐Ÿงช **Test your setup** in Settings โ†’ Models +5. ๐Ÿš€ **Start using Open Notebook!** --- -## Support +## Need Help? -- **Provider issues?** Check their documentation -- **Setup problems?** See [6-TROUBLESHOOTING](../6-TROUBLESHOOTING/index.md) -- **Need help?** Join [Discord community](https://discord.gg/37XJPXfz2w) +- **Setup issues?** See [AI Providers Configuration](../5-CONFIGURATION/ai-providers.md) for detailed troubleshooting per provider +- **General problems?** Check [Troubleshooting Guide](../6-TROUBLESHOOTING/index.md) +- **Questions?** Join [Discord community](https://discord.gg/37XJPXfz2w) diff --git a/docs/5-CONFIGURATION/advanced.md b/docs/5-CONFIGURATION/advanced.md index b2fba70..cc98fb9 100644 --- a/docs/5-CONFIGURATION/advanced.md +++ b/docs/5-CONFIGURATION/advanced.md @@ -116,6 +116,63 @@ Then visit https://smith.langchain.com to see traces. --- +## Port Configuration + +### Default Ports + +``` +Frontend: 8502 (Docker deployment) +Frontend: 3000 (Development from source) +API: 5055 +SurrealDB: 8000 +``` + +### Changing Frontend Port + +Edit `docker-compose.yml`: + +```yaml +services: + open-notebook: + ports: + - "8001:8502" # Change from 8502 to 8001 +``` + +Access at: `http://localhost:8001` + +API auto-detects to: `http://localhost:5055` โœ“ + +### Changing API Port + +```yaml +services: + open-notebook: + ports: + - "127.0.0.1:8502:8502" # Frontend + - "5056:5055" # Change API from 5055 to 5056 + environment: + - API_URL=http://localhost:5056 # Update API_URL +``` + +Access API directly: `http://localhost:5056/docs` + +**Note:** When changing API port, you must set `API_URL` explicitly since auto-detection assumes port 5055. + +### Changing SurrealDB Port + +```yaml +services: + surrealdb: + ports: + - "8001:8000" # Change from 8000 to 8001 + environment: + - SURREAL_URL=ws://surrealdb:8001/rpc # Update connection URL +``` + +**Important:** Internal Docker network uses container name (`surrealdb`), not `localhost`. + +--- + ## SSL/TLS Configuration ### Custom CA Certificate diff --git a/docs/5-CONFIGURATION/ai-providers.md b/docs/5-CONFIGURATION/ai-providers.md index ad65a22..9ca7aa3 100644 --- a/docs/5-CONFIGURATION/ai-providers.md +++ b/docs/5-CONFIGURATION/ai-providers.md @@ -27,15 +27,15 @@ OPENAI_API_KEY=sk-proj-xxxxx ``` **Available Models (in Open Notebook):** -- `gpt-4o` โ€” Best quality, fast, expensive +- `gpt-4o` โ€” Best quality, fast (latest version) - `gpt-4o-mini` โ€” Fast, cheap, good for testing -- `gpt-4-turbo` โ€” Older, good reasoning -- `gpt-3.5-turbo` โ€” Cheapest, basic quality +- `o1` โ€” Advanced reasoning model (slower, more expensive) +- `o1-mini` โ€” Faster reasoning model **Recommended:** - For general use: `gpt-4o` (best balance) - For testing/cheap: `gpt-4o-mini` (90% cheaper) -- For deep analysis: `gpt-4o` (best reasoning) +- For complex reasoning: `o1` (best for hard problems) **Cost Estimate:** ``` @@ -72,14 +72,15 @@ ANTHROPIC_API_KEY=sk-ant-xxxxx ``` **Available Models:** -- `claude-3-5-sonnet-20241022` โ€” Recommended, best quality +- `claude-sonnet-4-5-20250929` โ€” Latest, best quality (recommended) +- `claude-3-5-sonnet-20241022` โ€” Previous generation, still excellent - `claude-3-5-haiku-20241022` โ€” Fast, cheap -- `claude-3-opus-20250219` โ€” Most powerful, expensive +- `claude-opus-4-5-20251101` โ€” Most powerful, expensive **Recommended:** -- For general use: `claude-3-5-sonnet` (best overall) +- For general use: `claude-sonnet-4-5` (best overall, latest) - For cheap: `claude-3-5-haiku` (80% cheaper) -- For complex: `claude-3-opus` (most capable) +- For complex: `claude-opus-4-5` (most capable) **Cost Estimate:** ``` @@ -122,14 +123,15 @@ GEMINI_API_BASE_URL=https://generativelanguage.googleapis.com/v1beta/models ``` **Available Models:** -- `gemini-2.0-flash` โ€” Recommended, fast, cheap -- `gemini-1.5-pro` โ€” More capable, slower -- `gemini-1.5-flash` โ€” Fastest, cheapest +- `gemini-2.0-flash-exp` โ€” Latest experimental, fastest (recommended) +- `gemini-2.0-flash` โ€” Stable version, fast, cheap +- `gemini-1.5-pro-latest` โ€” More capable, longer context +- `gemini-1.5-flash` โ€” Previous generation, very cheap **Recommended:** -- For general use: `gemini-2.0-flash` (best value) +- For general use: `gemini-2.0-flash-exp` (best value, latest) - For cheap: `gemini-1.5-flash` (very cheap) -- For complex: `gemini-1.5-pro` (most capable) +- For complex/long context: `gemini-1.5-pro-latest` (2M token context) **Advantages:** - Very long context (1M tokens) @@ -163,13 +165,15 @@ GROQ_API_KEY=gsk_xxxxx ``` **Available Models:** -- `mixtral-8x7b-32768` โ€” Best on Groq -- `llama-3.3-70b-versatile` โ€” Good alternative -- `llama-2-70b-chat` โ€” Older but capable +- `llama-3.3-70b-versatile` โ€” Best on Groq (recommended) +- `llama-3.1-70b-versatile` โ€” Fast, capable +- `mixtral-8x7b-32768` โ€” Good alternative +- `gemma2-9b-it` โ€” Small, very fast **Recommended:** -- For speed/cost: `mixtral-8x7b-32768` -- For quality: `llama-3.3-70b-versatile` +- For quality: `llama-3.3-70b-versatile` (best overall) +- For speed: `gemma2-9b-it` (ultra-fast) +- For balance: `llama-3.1-70b-versatile` **Advantages:** - Ultra-fast inference @@ -207,17 +211,19 @@ OPENROUTER_API_KEY=sk-or-xxxxx ``` **Available Models (100+ options):** -- OpenAI models: `openai/gpt-4o`, `openai/gpt-4o-mini` -- Anthropic: `anthropic/claude-3.5-sonnet`, `anthropic/claude-3-haiku` -- Google: `google/gemini-pro`, `google/gemini-flash-1.5` -- Meta: `meta-llama/llama-3.3-70b-instruct` -- Mistral: `mistralai/mistral-large` +- OpenAI: `openai/gpt-4o`, `openai/o1` +- Anthropic: `anthropic/claude-sonnet-4.5`, `anthropic/claude-3.5-haiku` +- Google: `google/gemini-2.0-flash-exp`, `google/gemini-1.5-pro` +- Meta: `meta-llama/llama-3.3-70b-instruct`, `meta-llama/llama-3.1-405b-instruct` +- Mistral: `mistralai/mistral-large-2411` +- DeepSeek: `deepseek/deepseek-chat` - And many more... **Recommended:** -- For quality: `anthropic/claude-3.5-sonnet` -- For speed/cost: `google/gemini-flash-1.5` +- For quality: `anthropic/claude-sonnet-4.5` (best overall) +- For speed/cost: `google/gemini-2.0-flash-exp` (very fast, cheap) - For open-source: `meta-llama/llama-3.3-70b-instruct` +- For reasoning: `openai/o1` **Advantages:** - One API key for 100+ models @@ -269,17 +275,19 @@ OLLAMA_API_BASE=http://localhost:11434 ``` **Available Models:** -- `mistral` โ€” Recommended, balanced -- `llama2` โ€” Good general purpose -- `neural-chat` โ€” Conversational -- `phi` โ€” Small, fast -- `openchat` โ€” Open source +- `llama3.3:70b` โ€” Best quality (requires 40GB+ RAM) +- `llama3.1:8b` โ€” Recommended, balanced (8GB RAM) +- `qwen2.5:7b` โ€” Excellent for code and reasoning +- `mistral:7b` โ€” Good general purpose +- `phi3:3.8b` โ€” Small, fast (4GB RAM) +- `gemma2:9b` โ€” Google's model, balanced - Many more: `ollama list` to see available **Recommended:** -- For general use: `mistral` (best balance) -- For speed: `phi` (small, fast) -- For quality: `llama2` (larger, better) +- For quality (with GPU): `llama3.3:70b` (best) +- For general use: `llama3.1:8b` (best balance) +- For speed/low memory: `phi3:3.8b` (very fast) +- For coding: `qwen2.5:7b` (excellent at code) **Hardware Requirements:** ``` @@ -437,34 +445,22 @@ EMBEDDING_PROVIDER=openai # or custom --- -## Comparison Table - -| Provider | Speed | Cost | Quality | Privacy | Models | -|----------|-------|------|---------|---------|--------| -| **OpenAI** | Fast | Medium | Excellent | Low | Many | -| **Anthropic** | Fast | Medium | Excellent | Low | Few | -| **Google Gemini** | Fast | Medium | Good | Low | Few | -| **Groq** | Very Fast | Very Low | Good | Low | Few | -| **OpenRouter** | Varies | Varies | Varies | Low | 100+ | -| **Ollama (Local)** | Slow | Free | Good | Max | Many | -| **LM Studio** | Slow | Free | Good | Max | Many | -| **Azure OpenAI** | Fast | Medium | Excellent | High | Many | - ---- - ## Choosing Your Provider -**For most people:** OpenAI or Anthropic -- Cloud-based (no setup) -- Best quality -- Reasonable cost -- Simplest setup +**1. Don't want to run locally and don't want to mess around with different providers:** -**For budget-conscious:** Groq or Ollama +Use OpenAI +- Cloud-based +- Good quality +- Reasonable cost +- Simplest setup, supports all modes (text, embedding, tts, stt, etc) + +**For budget-conscious:** Groq, OpenRouter or Ollama - Groq: Super cheap cloud - Ollama: Free, but local +- OpenRouter: many open source models very accessible -**For privacy-first:** Ollama or LM Studio +**For privacy-first:** Ollama or LM Studio and [Speaches](local-tts.md) - Everything stays local - Works offline - No API keys sent anywhere @@ -486,3 +482,13 @@ EMBEDDING_PROVIDER=openai # or custom 6. **Verify it works** with a test chat Done! + +--- + +## Related + +- **[Environment Reference](environment-reference.md)** - Complete list of all environment variables +- **[Advanced Configuration](advanced.md)** - Timeouts, SSL, performance tuning +- **[Ollama Setup](ollama.md)** - Detailed Ollama configuration guide +- **[OpenAI-Compatible](openai-compatible.md)** - LM Studio and other compatible providers +- **[Troubleshooting](../6-TROUBLESHOOTING/quick-fixes.md)** - Common issues and fixes diff --git a/docs/5-CONFIGURATION/index.md b/docs/5-CONFIGURATION/index.md index 0bc8193..38f7eaa 100644 --- a/docs/5-CONFIGURATION/index.md +++ b/docs/5-CONFIGURATION/index.md @@ -17,44 +17,37 @@ Three things: ## Quick Decision: Which Provider? ### Option 1: Cloud Provider (Fastest) -- **OpenAI** (GPT-4o, GPT-4o-mini) -- **Anthropic** (Claude Sonnet, Haiku) +- **OpenRouter (recommended)** (access to all models with one key) +- **OpenAI** (GPT) +- **Anthropic** (Claude) - **Google Gemini** (multi-modal, long context) - **Groq** (ultra-fast inference) Setup: Get API key โ†’ Set env var โ†’ Done -Cost: $0.01-0.10 per 1K tokens - โ†’ Go to **[AI Providers Guide](ai-providers.md)** ### Option 2: Local (Free & Private) - **Ollama** (open-source models, on your machine) -- **LM Studio** (desktop app) -- **OpenAI-compatible** (LM Studio, etc.) -Setup: Install/run locally โ†’ Set endpoint โ†’ Done - -Cost: Free (electricity only) - -โ†’ Go to **[Ollama Setup](ai-providers.md#ollama-recommended-for-local)** +โ†’ Go to **[Ollama Setup](ollama.md)** ### Option 3: OpenAI-Compatible - **LM Studio** (local) -- **Text Generation UI** (local) - **Custom endpoints** -Setup: Point to your endpoint โ†’ Set API key โ†’ Done - -Cost: Depends on service - -โ†’ Go to **[OpenAI-Compatible Guide](ai-providers.md)** +โ†’ Go to **[OpenAI-Compatible Guide](openai-compatible.md)** --- -## Three Configuration Files +## Configuration File + +Use the right file depending on your setup. ### `.env` (Local Development) + +You will only use .env if you are running Open Notebook locally. + ``` Located in: project root Use for: Development on your machine @@ -62,6 +55,8 @@ Format: KEY=value, one per line ``` ### `docker.env` (Docker Deployment) + +You will use this file to hold your environment variables if you are using docker-compose and prefer not to put the variables directly in the compose file. ``` Located in: project root (or ./docker) Use for: Docker deployments @@ -69,20 +64,17 @@ Format: Same as .env Loaded by: docker-compose.yml ``` -### `.env.local` (Next.js Frontend) -``` -Located in: frontend/ -Use for: Frontend-specific settings -Currently: Just NEXT_PUBLIC_API_URL -``` - --- ## Most Important Settings -### For Every Setup +All of the settings provided below are to be placed inside your environment file (.env or docker.env depending on your setup). + + +### Surreal Database + +This is the database used by the app. -**1. Surreal Database** ``` SURREAL_URL=ws://surrealdb:8000/rpc SURREAL_USER=root @@ -91,27 +83,47 @@ SURREAL_NAMESPACE=open_notebook SURREAL_DATABASE=open_notebook ``` -Usually pre-configured. Only change if using different database. +> The only thing that is critical to not miss is the hostname in the `SURREAL_URL`. Check what URL to use based on your deployment, [here](database.md). + + +### AI Provider (API Key or URL) + +We need access to LLMs in order for the app to work. You can use any of the support AI Providers by adding their API Keys. -**2. AI Provider API Key** ``` -Pick ONE: OPENAI_API_KEY=sk-... ANTHROPIC_API_KEY=sk-ant-... GOOGLE_API_KEY=... -GROQ_API_KEY=... -# Or for Ollama: No key needed +OPENROUTER_API_KEY=... ``` -Required. You must set at least one. +Or, if you are planning to use only local providers, you can setup Ollama by configuring it's base URL. This will get you set and ready with text and embeddings in one go: + +``` +OLLAMA_BASE_URL=http://localhost:11434 +``` + +> A lot of people screw up on the Ollama BASE URL by not knowing how to point to their Ollama installation. if you are having trouble connecting to Ollama, see [here](ollama.md). + +You can also use LM Studio locally if you prefer by using it as an OpenAI compatible endpoint. + +``` +OPENAI_COMPATIBLE_BASE_URL=http://localhost:1234/v1 +OPENAI_COMPATIBLE_BASE_URL_EMBEDDING=http://localhost:1234/v1 +``` + +> For more installation on using OpenAI compatible endpoints, see [here](openai-compatible.md). + + +### API URL (If Behind Reverse Proxy) +You only need to worry about this if you are deploying on a proxy or if you are changing port information. Otherwise, skip this. -**3. API URL (If Behind Reverse Proxy)** ``` API_URL=https://your-domain.com # Usually auto-detected. Only set if needed. ``` -Optional. Auto-detection works for most setups. +Auto-detection works for most setups. --- @@ -174,13 +186,10 @@ AZURE_OPENAI_API_VERSION=2024-12-01-preview - Database vs. namespace - Running your own SurrealDB -### [Server](server.md) -- API_URL (when and how) +### [Advanced](advanced.md) - Ports and networking - Timeouts and concurrency - SSL/security - -### [Advanced](advanced.md) - Retry configuration - Worker concurrency - Language models & embeddings @@ -205,6 +214,11 @@ AZURE_OPENAI_API_VERSION=2024-12-01-preview - Voice options - Docker networking +### [Ollama](ollama.md) +- Setting up and pointing to an Ollama server +- Downloading models +- Using embedding + ### [OpenAI-Compatible Providers](openai-compatible.md) - LM Studio, vLLM, Text Generation WebUI - Connection configuration diff --git a/docs/5-CONFIGURATION/ollama.md b/docs/5-CONFIGURATION/ollama.md new file mode 100644 index 0000000..3b4d490 --- /dev/null +++ b/docs/5-CONFIGURATION/ollama.md @@ -0,0 +1,627 @@ +# Ollama Setup Guide + +Ollama provides free, local AI models that run on your own hardware. This guide covers everything you need to know about setting up Ollama with Open Notebook, including different deployment scenarios and network configurations. + +## Why Choose Ollama? + +- **๐Ÿ†“ Completely Free**: No API costs after initial setup +- **๐Ÿ”’ Full Privacy**: Your data never leaves your local network +- **๐Ÿ“ฑ Offline Capable**: Works without internet connection +- **๐Ÿš€ Fast**: Local inference with no network latency +- **๐Ÿง  Reasoning Models**: Support for advanced reasoning models like DeepSeek-R1 +- **๐Ÿ’พ Model Variety**: Access to hundreds of open-source models + +## Quick Start + +### 1. Install Ollama + +**Linux/macOS:** +```bash +curl -fsSL https://ollama.ai/install.sh | sh +``` + +**Windows:** +Download and install from [ollama.ai](https://ollama.ai/download) + +### 2. Pull Required Models + +```bash +# Language models (choose one or more) +ollama pull qwen3 # Excellent general purpose, 7B parameters +ollama pull gemma3 # Google's model, good performance +ollama pull deepseek-r1 # Advanced reasoning model +ollama pull phi4 # Microsoft's efficient model + +# Embedding model (required for search) +ollama pull mxbai-embed-large # Best embedding model for Ollama +``` + +### 3. Configure Open Notebook + +**For local installation:** +```bash +export OLLAMA_API_BASE=http://localhost:11434 +``` + +**For Docker installation:** +```bash +export OLLAMA_API_BASE=http://host.docker.internal:11434 +``` + +## Network Configuration Guide + +The `OLLAMA_API_BASE` environment variable tells Open Notebook where to find your Ollama server. The correct value depends on your deployment scenario: + +### Scenario 1: Local Installation (Same Machine) + +When both Open Notebook and Ollama run directly on your machine: + +```bash +export OLLAMA_API_BASE=http://localhost:11434 +# or +export OLLAMA_API_BASE=http://127.0.0.1:11434 +``` + +**Use `localhost` vs `127.0.0.1`:** +- **localhost**: Recommended, works with most configurations +- **127.0.0.1**: Use if you have DNS resolution issues with localhost + +### Scenario 2: Open Notebook in Docker, Ollama on Host + +When Open Notebook runs in Docker but Ollama runs on your host machine: + +```bash +export OLLAMA_API_BASE=http://host.docker.internal:11434 +``` + +**โš ๏ธ CRITICAL: Ollama must accept external connections:** +```bash +# Start Ollama with external access enabled +export OLLAMA_HOST=0.0.0.0:11434 +ollama serve +``` + +**Why `host.docker.internal`?** +- Docker containers can't reach `localhost` on the host +- `host.docker.internal` is Docker's special hostname for the host machine +- Available on Docker Desktop for Mac/Windows and recent Linux versions + +**Why `OLLAMA_HOST=0.0.0.0:11434`?** +- By default, Ollama only binds to localhost and rejects external connections +- Docker containers are considered "external" even when running on the same machine +- Setting `OLLAMA_HOST=0.0.0.0:11434` allows connections from Docker containers + +### Scenario 3: Both in Docker (Same Compose) + +When both Open Notebook and Ollama run in the same Docker Compose stack: + +```bash +export OLLAMA_API_BASE=http://ollama:11434 +``` + +**Docker Compose Example:** + +```yaml +version: '3.8' +services: + open-notebook: + image: lfnovo/open_notebook:v1-latest-single + ports: + - "8502:8502" + - "5055:5055" + environment: + - OLLAMA_API_BASE=http://ollama:11434 + volumes: + - ./notebook_data:/app/data + - ./surreal_data:/mydata + depends_on: + - ollama + + ollama: + image: ollama/ollama:v1-latest + ports: + - "11434:11434" + volumes: + - ollama_data:/root/.ollama + # Optional: GPU support + deploy: + resources: + reservations: + devices: + - driver: nvidia + count: 1 + capabilities: [gpu] + +volumes: + ollama_data: +``` + +### Scenario 4: Remote Ollama Server + +When Ollama runs on a different machine in your network: + +```bash +export OLLAMA_API_BASE=http://192.168.1.100:11434 +# Replace 192.168.1.100 with your Ollama server's IP address +``` + +**Security Note:** Only use this in trusted networks. Ollama doesn't have built-in authentication. + +### Scenario 5: Ollama with Custom Port + +If you've configured Ollama to use a different port: + +```bash +# Start Ollama on custom port +OLLAMA_HOST=0.0.0.0:8080 ollama serve + +# Configure Open Notebook +export OLLAMA_API_BASE=http://localhost:8080 +``` + +## Model Recommendations + +### Language Models + +| Model | Size | Best For | Quality | Speed | +|-------|------|----------|---------|-------| +| **qwen3** | 7B | General purpose, coding | Excellent | Fast | +| **deepseek-r1** | 7B | Reasoning, problem-solving | Exceptional | Medium | +| **gemma3** | 7B | Balanced performance | Very Good | Fast | +| **phi4** | 14B | Efficiency on small hardware | Good | Very Fast | +| **llama3** | 8B | General purpose | Very Good | Medium | + +### Embedding Models + +| Model | Best For | Performance | +|-------|----------|-------------| +| **mxbai-embed-large** | General search | Excellent | +| **nomic-embed-text** | Document similarity | Good | +| **all-minilm** | Lightweight option | Fair | + +### Installation Commands + +```bash +# Essential models +ollama pull qwen3 # Primary language model +ollama pull mxbai-embed-large # Search embeddings + +# Optional reasoning model +ollama pull deepseek-r1 # Advanced reasoning + +# Alternative language models +ollama pull gemma3 # Google's model +ollama pull phi4 # Microsoft's efficient model +``` + +## Hardware Requirements + +### Minimum Requirements +- **RAM**: 8GB (for 7B models) +- **Storage**: 10GB free space per model +- **CPU**: Modern multi-core processor + +### Recommended Setup +- **RAM**: 16GB+ (for multiple models) +- **Storage**: SSD with 50GB+ free space +- **GPU**: NVIDIA GPU with 8GB+ VRAM (optional but faster) + +### GPU Acceleration + +**NVIDIA GPU (CUDA):** +```bash +# Install NVIDIA Container Toolkit for Docker +# Then use the Docker Compose example above with GPU support + +# For local installation, Ollama auto-detects CUDA +ollama pull qwen3 +``` + +**Apple Silicon (M1/M2/M3):** +```bash +# Ollama automatically uses Metal acceleration +# No additional setup required +ollama pull qwen3 +``` + +**AMD GPUs:** +```bash +# ROCm support varies by model and system +# Check Ollama documentation for latest compatibility +``` + +## Troubleshooting + +### Common Issues + +**1. "Ollama unavailable" in Open Notebook** + +**Check Ollama is running:** +```bash +curl http://localhost:11434/api/tags +``` + +**Verify environment variable:** +```bash +echo $OLLAMA_API_BASE +``` + +**โš ๏ธ IMPORTANT: Enable external connections (most common fix):** +```bash +# If Open Notebook runs in Docker or on a different machine, +# Ollama must bind to all interfaces, not just localhost +export OLLAMA_HOST=0.0.0.0:11434 +ollama serve +``` +> **Why this is needed:** By default, Ollama only accepts connections from `localhost` (127.0.0.1). When Open Notebook runs in Docker or on a different machine, it can't reach Ollama unless you configure `OLLAMA_HOST=0.0.0.0:11434` to accept external connections. + +**Restart Ollama:** +```bash +# Linux/macOS +sudo systemctl restart ollama +# or +ollama serve + +# Windows +# Restart from system tray or Services +``` + +**2. Docker networking issues** + +**From inside Open Notebook container, test Ollama:** +```bash +# Get into container +docker exec -it open-notebook bash + +# Test connection +curl http://host.docker.internal:11434/api/tags +``` + +**3. Models not downloading** + +**Check disk space:** +```bash +df -h +``` + +**Manual model pull:** +```bash +ollama pull qwen3 --verbose +``` + +**Clear failed downloads:** +```bash +ollama rm qwen3 +ollama pull qwen3 +``` + +**4. Slow performance** + +**Check model size vs available RAM:** +```bash +ollama ps # Show running models +free -h # Check available memory +``` + +**Use smaller models:** +```bash +ollama pull phi4 # Instead of larger models +ollama pull gemma3:2b # 2B parameter variant +``` + +**5. Port conflicts** + +**Check what's using port 11434:** +```bash +lsof -i :11434 +netstat -tulpn | grep 11434 +``` + +**Use custom port:** +```bash +OLLAMA_HOST=0.0.0.0:8080 ollama serve +export OLLAMA_API_BASE=http://localhost:8080 +``` + +### Docker-Specific Troubleshooting + +**1. Host networking on Linux:** +```bash +# Use host networking if host.docker.internal doesn't work +docker run --network host lfnovo/open_notebook:v1-latest-single +export OLLAMA_API_BASE=http://localhost:11434 +``` + +**2. Custom bridge network:** +```yaml +version: '3.8' +networks: + ollama_network: + driver: bridge + +services: + open-notebook: + networks: + - ollama_network + environment: + - OLLAMA_API_BASE=http://ollama:11434 + + ollama: + networks: + - ollama_network +``` + +**3. Firewall issues:** +```bash +# Allow Ollama port through firewall +sudo ufw allow 11434 +# or +sudo firewall-cmd --add-port=11434/tcp --permanent +``` + +## Performance Optimization + +### Model Management + +**List installed models:** +```bash +ollama list +``` + +**Remove unused models:** +```bash +ollama rm model_name +``` + +**Show running models:** +```bash +ollama ps +``` + +**Preload models for faster startup:** +```bash +# Keep model in memory +curl http://localhost:11434/api/generate -d '{ + "model": "qwen3", + "prompt": "test", + "keep_alive": -1 +}' +``` + +### System Optimization + +**Linux: Increase file limits:** +```bash +echo "* soft nofile 65536" >> /etc/security/limits.conf +echo "* hard nofile 65536" >> /etc/security/limits.conf +``` + +**macOS: Increase memory limits:** +```bash +# Add to ~/.zshrc or ~/.bash_profile +export OLLAMA_MAX_LOADED_MODELS=2 +export OLLAMA_NUM_PARALLEL=4 +``` + +**Docker: Resource allocation:** +```yaml +services: + ollama: + deploy: + resources: + limits: + memory: 8G + cpus: '4' +``` + +## Advanced Configuration + +### Environment Variables + +```bash +# Ollama server configuration +export OLLAMA_HOST=0.0.0.0:11434 # Bind to all interfaces +export OLLAMA_KEEP_ALIVE=5m # Keep models in memory +export OLLAMA_MAX_LOADED_MODELS=3 # Max concurrent models +export OLLAMA_MAX_QUEUE=512 # Request queue size +export OLLAMA_NUM_PARALLEL=4 # Parallel request handling +export OLLAMA_FLASH_ATTENTION=1 # Enable flash attention (if supported) + +# Open Notebook configuration +export OLLAMA_API_BASE=http://localhost:11434 +``` + +### SSL Configuration (Self-Signed Certificates) + +If you're running Ollama behind a reverse proxy with self-signed SSL certificates (e.g., Caddy, nginx with custom certs), you may encounter SSL verification errors: + +``` +[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate +``` + +**Solutions:** + +**Option 1: Use a custom CA bundle (recommended)** +```bash +# Point to your CA certificate file +export ESPERANTO_SSL_CA_BUNDLE=/path/to/your/ca-bundle.pem +``` + +**Option 2: Disable SSL verification (development only)** +```bash +# WARNING: Only use in trusted development environments +export ESPERANTO_SSL_VERIFY=false +``` + +**Docker Compose example with SSL configuration:** +```yaml +services: + open-notebook: + image: lfnovo/open_notebook:v1-latest-single + environment: + - OLLAMA_API_BASE=https://ollama.local:11434 + # Option 1: Custom CA bundle + - ESPERANTO_SSL_CA_BUNDLE=/certs/ca-bundle.pem + # Option 2: Disable verification (dev only) + # - ESPERANTO_SSL_VERIFY=false + volumes: + - /path/to/your/ca-bundle.pem:/certs/ca-bundle.pem:ro +``` + +> **Security Note:** Disabling SSL verification exposes you to man-in-the-middle attacks. Always prefer using a custom CA bundle in production environments. + +### Custom Model Imports + +**Import custom models:** +```bash +# Create Modelfile +cat > Modelfile << EOF +FROM qwen3 +PARAMETER temperature 0.7 +PARAMETER top_p 0.9 +SYSTEM "You are a helpful research assistant." +EOF + +# Create custom model +ollama create my-research-model -f Modelfile +``` + +**Use in Open Notebook:** +1. Go to Models +2. Add new model: `my-research-model` +3. Set as default for specific tasks + +### Monitoring and Logging + +**Monitor Ollama logs:** +```bash +# Linux (systemd) +journalctl -u ollama -f + +# Docker +docker logs -f ollama + +# Manual run with verbose logging +OLLAMA_DEBUG=1 ollama serve +``` + +**Resource monitoring:** +```bash +# CPU and memory usage +htop + +# GPU usage (NVIDIA) +nvidia-smi -l 1 + +# Model-specific metrics +ollama ps +``` + +## Integration Examples + +### Python Script Integration + +```python +import requests +import os + +# Test Ollama connection +ollama_base = os.environ.get('OLLAMA_API_BASE', 'http://localhost:11434') +response = requests.get(f'{ollama_base}/api/tags') +print(f"Available models: {response.json()}") + +# Generate text +payload = { + "model": "qwen3", + "prompt": "Explain quantum computing", + "stream": False +} +response = requests.post(f'{ollama_base}/api/generate', json=payload) +print(response.json()['response']) +``` + +### Health Check Script + +```bash +#!/bin/bash +# ollama-health-check.sh + +OLLAMA_API_BASE=${OLLAMA_API_BASE:-"http://localhost:11434"} + +echo "Checking Ollama health..." +if curl -s "${OLLAMA_API_BASE}/api/tags" > /dev/null; then + echo "โœ… Ollama is running" + echo "Available models:" + curl -s "${OLLAMA_API_BASE}/api/tags" | jq -r '.models[].name' +else + echo "โŒ Ollama is not accessible at ${OLLAMA_API_BASE}" + exit 1 +fi +``` + +## Migration from Other Providers + +### Coming from OpenAI + +**Similar performance models:** +- GPT-4 โ†’ `qwen3` or `deepseek-r1` +- GPT-3.5 โ†’ `gemma3` or `phi4` +- text-embedding-ada-002 โ†’ `mxbai-embed-large` + +**Cost comparison:** +- OpenAI: $0.01-0.06 per 1K tokens +- Ollama: $0 after hardware investment + +### Coming from Anthropic + +**Claude replacement suggestions:** +- Claude 3.5 Sonnet โ†’ `deepseek-r1` (reasoning) +- Claude 3 Haiku โ†’ `phi4` (speed) + +## Best Practices + +### Security + +1. **Network Security:** + - Run Ollama only on trusted networks + - Use firewall rules to limit access + - Consider VPN for remote access + +2. **Model Verification:** + - Only pull models from trusted sources + - Verify model checksums when possible + +3. **Resource Limits:** + - Set memory and CPU limits in production + - Monitor resource usage regularly + +### Performance + +1. **Model Selection:** + - Use appropriate model size for your hardware + - Smaller models for simple tasks + - Reasoning models only when needed + +2. **Resource Management:** + - Preload frequently used models + - Remove unused models regularly + - Monitor system resources + +3. **Network Optimization:** + - Use local networks for better latency + - Consider SSD storage for faster model loading + +## Getting Help + +**Community Resources:** +- [Ollama GitHub](https://github.com/jmorganca/ollama) - Official repository +- [Ollama Discord](https://discord.gg/ollama) - Community support +- [Open Notebook Discord](https://discord.gg/37XJPXfz2w) - Integration help + +**Debugging Resources:** +- Check Ollama logs for error messages +- Test connection with curl commands +- Verify environment variables +- Monitor system resources + +This comprehensive guide should help you successfully deploy and optimize Ollama with Open Notebook. Start with the Quick Start section and refer to specific scenarios as needed. \ No newline at end of file diff --git a/docs/5-CONFIGURATION/openai-compatible.md b/docs/5-CONFIGURATION/openai-compatible.md index e82ea5a..9624a58 100644 --- a/docs/5-CONFIGURATION/openai-compatible.md +++ b/docs/5-CONFIGURATION/openai-compatible.md @@ -72,8 +72,8 @@ OPENAI_COMPATIBLE_API_KEY=optional-api-key ### Embeddings ```bash -OPENAI_COMPATIBLE_BASE_URL_EMBED=http://localhost:1234/v1 -OPENAI_COMPATIBLE_API_KEY_EMBED=optional-api-key +OPENAI_COMPATIBLE_BASE_URL_EMBEDDING=http://localhost:1234/v1 +OPENAI_COMPATIBLE_BASE_URL_EMBEDDING=optional-api-key ``` ### Text-to-Speech @@ -331,7 +331,7 @@ You can use different compatible servers for different purposes: OPENAI_COMPATIBLE_BASE_URL=http://localhost:1234/v1 # Embeddings from different server -OPENAI_COMPATIBLE_BASE_URL_EMBED=http://localhost:8080/v1 +OPENAI_COMPATIBLE_BASE_URL_EMBEDDING=http://localhost:8080/v1 # TTS from Speaches OPENAI_COMPATIBLE_BASE_URL_TTS=http://localhost:8969/v1 @@ -391,4 +391,4 @@ Use OpenAI-compatible when: - **[Local TTS Setup](local-tts.md)** - Text-to-speech with Speaches - **[AI Providers](ai-providers.md)** - All provider options -- **[Ollama Setup](../4-AI-PROVIDERS/index.md)** - Native Ollama integration +- **[Ollama Setup](ollama.md)** - Native Ollama integration diff --git a/docs/5-CONFIGURATION/reverse-proxy.md b/docs/5-CONFIGURATION/reverse-proxy.md index 8eaaf7d..ea88b46 100644 --- a/docs/5-CONFIGURATION/reverse-proxy.md +++ b/docs/5-CONFIGURATION/reverse-proxy.md @@ -106,6 +106,33 @@ API_URL=https://your-domain.com --- +## Understanding API_URL + +The frontend uses a three-tier priority system to determine the API URL: + +1. **Runtime Configuration** (Highest Priority): `API_URL` environment variable set at container runtime +2. **Build-time Configuration**: `NEXT_PUBLIC_API_URL` baked into the Docker image +3. **Auto-detection** (Fallback): Infers from the incoming HTTP request headers + +### Auto-Detection Details + +When `API_URL` is not set, the Next.js frontend: +- Analyzes the incoming HTTP request +- Extracts the hostname from the `host` header +- Respects the `X-Forwarded-Proto` header (for HTTPS behind reverse proxies) +- Constructs the API URL as `{protocol}://{hostname}:5055` +- Example: Request to `http://10.20.30.20:8502` โ†’ API URL becomes `http://10.20.30.20:5055` + +**Why set API_URL explicitly?** +- **Reliability**: Auto-detection can fail with complex proxy setups +- **HTTPS**: Ensures frontend uses `https://` when behind SSL-terminating proxy +- **Custom domains**: Works correctly with domain names instead of IP addresses +- **Port mapping**: Avoids exposing port 5055 in the URL when using reverse proxy + +**Important**: Don't include `/api` at the end - the system adds this automatically! + +--- + ## Complete Docker Compose Example ```yaml @@ -225,6 +252,190 @@ location / { --- +## Advanced Scenarios + +### Remote Server Access (LAN/VPS) + +Accessing Open Notebook from a different machine on your network: + +**Step 1: Get your server IP** +```bash +# On the server running Open Notebook: +hostname -I +# or +ifconfig | grep "inet " +# Note the IP (e.g., 192.168.1.100) +``` + +**Step 2: Configure API_URL** +```bash +# In docker-compose.yml or .env: +API_URL=http://192.168.1.100:5055 +``` + +**Step 3: Expose ports** +```yaml +services: + open-notebook: + image: lfnovo/open_notebook:v1-latest-single + environment: + - API_URL=http://192.168.1.100:5055 + ports: + - "8502:8502" + - "5055:5055" +``` + +**Step 4: Access from client machine** +```bash +# In browser on other machine: +http://192.168.1.100:8502 +``` + +**Troubleshooting**: +- Check firewall: `sudo ufw allow 8502 && sudo ufw allow 5055` +- Verify connectivity: `ping 192.168.1.100` from client machine +- Test port: `telnet 192.168.1.100 8502` from client machine + +--- + +### API on Separate Subdomain + +Host the API and frontend on different subdomains: + +**docker-compose.yml:** +```yaml +services: + open-notebook: + image: lfnovo/open_notebook:v1-latest-single + environment: + - API_URL=https://api.notebook.example.com + - OPENAI_API_KEY=${OPENAI_API_KEY} + # Don't expose ports (nginx handles routing) +``` + +**nginx.conf:** +```nginx +# Frontend server +server { + listen 443 ssl http2; + server_name notebook.example.com; + + ssl_certificate /etc/nginx/ssl/fullchain.pem; + ssl_certificate_key /etc/nginx/ssl/privkey.pem; + + location / { + proxy_pass http://open-notebook:8502; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_cache_bypass $http_upgrade; + } +} + +# API server (separate subdomain) +server { + listen 443 ssl http2; + server_name api.notebook.example.com; + + ssl_certificate /etc/nginx/ssl/fullchain.pem; + ssl_certificate_key /etc/nginx/ssl/privkey.pem; + + location / { + proxy_pass http://open-notebook:5055; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } +} +``` + +**Use case**: Separate DNS records, different rate limiting, or isolated API access control. + +--- + +### Multi-Container Deployment (Advanced) + +For complex deployments with separate frontend and API containers: + +**docker-compose.yml:** +```yaml +services: + frontend: + image: lfnovo/open_notebook_frontend:v1-latest + environment: + - API_URL=https://notebook.example.com + ports: + - "8502:8502" + + api: + image: lfnovo/open_notebook_api:v1-latest + environment: + - OPENAI_API_KEY=${OPENAI_API_KEY} + ports: + - "5055:5055" + depends_on: + - surrealdb + + surrealdb: + image: surrealdb/surrealdb:latest + command: start --log trace --user root --pass root file:/mydata/database.db + ports: + - "8000:8000" + volumes: + - ./surreal_data:/mydata +``` + +**nginx.conf:** +```nginx +http { + upstream frontend { + server frontend:8502; + } + + upstream api { + server api:5055; + } + + server { + listen 443 ssl http2; + server_name notebook.example.com; + + # API routes + location /api/ { + proxy_pass http://api/api/; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + # Frontend (catch-all) + location / { + proxy_pass http://frontend; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_cache_bypass $http_upgrade; + } + } +} +``` + +**Note**: Most users should use the single-container approach (`v1-latest-single`). Multi-container is only needed for custom scaling or isolation requirements. + +--- + ## SSL Certificates ### Let's Encrypt with Certbot @@ -309,19 +520,219 @@ proxy_send_timeout 300s; --- +### How to Debug Configuration Issues + +**Step 1: Check browser console** (F12 โ†’ Console tab) +``` +Look for messages starting with ๐Ÿ”ง [Config] +These show the configuration detection process +You'll see which API URL is being used +``` + +**Example good output:** +``` +โœ… [Config] Runtime API URL from server: https://your-domain.com +``` + +**Example bad output:** +``` +โŒ [Config] Failed to fetch runtime config +โš ๏ธ [Config] Using auto-detected URL: http://localhost:5055 +``` + +**Step 2: Test API directly** +```bash +# Should return JSON config +curl https://your-domain.com/api/config + +# Expected output: +{"openai_api_key_set":true,"anthropic_api_key_set":false,...} +``` + +**Step 3: Check Docker logs** +```bash +docker logs open-notebook + +# Look for: +# - Frontend startup: "โ–ฒ Next.js ready on http://0.0.0.0:8502" +# - API startup: "INFO: Uvicorn running on http://0.0.0.0:5055" +# - Connection errors or CORS issues +``` + +**Step 4: Verify environment variable** +```bash +docker exec open-notebook env | grep API_URL + +# Should show: +# API_URL=https://your-domain.com +``` + +--- + +### Frontend Adds `:5055` to URL (Versions โ‰ค 1.0.10) + +**Symptoms** (only in older versions): +- You set `API_URL=https://your-domain.com` +- Browser console shows: "Attempted URL: https://your-domain.com:5055/api/config" +- CORS errors with "Status code: (null)" + +**Root Cause:** +In versions โ‰ค 1.0.10, the frontend's config endpoint was at `/api/runtime-config`, which got intercepted by reverse proxies routing all `/api/*` requests to the backend. This prevented the frontend from reading the `API_URL` environment variable. + +**Solution:** +Upgrade to version 1.0.11 or later. The config endpoint has been moved to `/config` which avoids the `/api/*` routing conflict. + +**Verification:** +Check browser console (F12) - should see: `โœ… [Config] Runtime API URL from server: https://your-domain.com` + +**If you can't upgrade**, explicitly configure the `/config` route: +```nginx +# Only needed for versions โ‰ค 1.0.10 +location = /config { + proxy_pass http://open-notebook:8502; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-Proto $scheme; +} +``` + +--- + +### CORS Errors + +**Symptoms:** +``` +Access-Control-Allow-Origin header is missing +Cross-Origin Request Blocked +Response to preflight request doesn't pass access control check +``` + +**Possible Causes:** + +1. **Missing proxy headers**: + ```nginx + # Make sure these are set: + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $host; + ``` + +2. **API_URL protocol mismatch**: + ```bash + # Frontend is HTTPS, but API_URL is HTTP: + API_URL=http://notebook.example.com # โŒ Wrong + API_URL=https://notebook.example.com # โœ… Correct + ``` + +3. **Reverse proxy not forwarding `/api/*` correctly**: + ```nginx + # Make sure this works: + location /api/ { + proxy_pass http://open-notebook:5055/api/; # Note the trailing slash! + } + ``` + +--- + +### Missing Authorization Header + +**Symptoms:** +```json +{"detail": "Missing authorization header"} +``` + +This happens when: +- You have set `OPEN_NOTEBOOK_PASSWORD` for authentication +- You're trying to access `/api/config` directly without logging in first + +**Solution:** +This is **expected behavior**! The frontend handles authentication automatically. Just: +1. Access the frontend URL (not `/api/` directly) +2. Log in through the UI +3. The frontend will handle authorization headers for all API calls + +**For API integrations:** Include the password in the Authorization header: +```bash +curl -H "Authorization: Bearer your-password-here" \ + https://your-domain.com/api/config +``` + +--- + +### SSL/TLS Certificate Errors + +**Symptoms:** +- Browser shows "Your connection is not private" +- Certificate warnings +- Mixed content errors + +**Solutions:** + +1. **Use Let's Encrypt** (recommended): + ```bash + sudo certbot --nginx -d notebook.example.com + ``` + +2. **Check certificate paths** in nginx: + ```nginx + ssl_certificate /etc/nginx/ssl/fullchain.pem; # Full chain + ssl_certificate_key /etc/nginx/ssl/privkey.pem; # Private key + ``` + +3. **Verify certificate is valid**: + ```bash + openssl x509 -in /etc/nginx/ssl/fullchain.pem -text -noout + ``` + +4. **For development**, use self-signed (not for production): + ```bash + openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ + -keyout ssl/privkey.pem -out ssl/fullchain.pem \ + -subj "/CN=localhost" + ``` + +--- + ## Best Practices 1. **Always use HTTPS** in production -2. **Set API_URL explicitly** when using reverse proxies -3. **Bind to localhost** (`127.0.0.1:8502`) and let proxy handle public access -4. **Enable security headers** (HSTS, X-Frame-Options, etc.) -5. **Set up certificate renewal** for Let's Encrypt -6. **Test your configuration** before going live +2. **Set API_URL explicitly** when using reverse proxies to avoid auto-detection issues +3. **Bind to localhost** (`127.0.0.1:8502`) and let proxy handle public access for security +4. **Enable security headers** (HSTS, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection) +5. **Set up certificate renewal** for Let's Encrypt (usually automatic with certbot) +6. **Keep ports 5055 and 8502 accessible** from your reverse proxy container (use Docker networks) +7. **Use environment files** (`.env` or `docker.env`) to manage configuration securely +8. **Test your configuration** before going live: + - Check browser console for config messages + - Test API: `curl https://your-domain.com/api/config` + - Verify authentication works + - Check long-running operations (podcast generation) +9. **Monitor logs** regularly: `docker logs open-notebook` +10. **Don't include `/api` in API_URL** - the system adds this automatically + +--- + +## Legacy Configurations (Pre-v1.1) + +If you're running Open Notebook **version 1.0.x or earlier**, you may need to use the legacy two-port configuration where you explicitly route `/api/*` to port 5055. + +**Check your version:** +```bash +docker exec open-notebook cat /app/package.json | grep version +``` + +**If version < 1.1.0**, you may need: +- Explicit `/api/*` routing to port 5055 in reverse proxy +- Explicit `/config` endpoint routing for versions โ‰ค 1.0.10 +- See the "Frontend Adds `:5055` to URL" troubleshooting section above + +**Recommendation:** Upgrade to v1.1+ for simplified configuration and better performance. --- ## Related - **[Security Configuration](security.md)** - Password protection and hardening -- **[Server Configuration](server.md)** - Ports and API settings +- **[Advanced Configuration](advanced.md)** - Ports, timeouts, and SSL settings - **[Troubleshooting](../6-TROUBLESHOOTING/connection-issues.md)** - Connection problems +- **[Docker Deployment](../1-INSTALLATION/docker-compose.md)** - Complete deployment guide diff --git a/docs/5-CONFIGURATION/security.md b/docs/5-CONFIGURATION/security.md index c1eaa86..ddf389d 100644 --- a/docs/5-CONFIGURATION/security.md +++ b/docs/5-CONFIGURATION/security.md @@ -6,13 +6,12 @@ Protect your Open Notebook deployment with password authentication and productio ## When to Use Password Protection -### Use It For: +### Use it for: - Public cloud deployments (PikaPods, Railway, DigitalOcean) - Shared network environments -- Team deployments - Any deployment accessible beyond localhost -### Skip It For: +### You can skip it for: - Local development on your machine - Private, isolated networks - Single-user local setups @@ -330,5 +329,5 @@ If you discover security vulnerabilities: ## Related - **[Reverse Proxy](reverse-proxy.md)** - HTTPS and SSL setup -- **[Server Configuration](server.md)** - API settings +- **[Advanced Configuration](advanced.md)** - Ports, timeouts, and SSL settings - **[Environment Reference](environment-reference.md)** - All configuration options diff --git a/docs/5-CONFIGURATION/server.md b/docs/5-CONFIGURATION/server.md deleted file mode 100644 index 8a8c201..0000000 --- a/docs/5-CONFIGURATION/server.md +++ /dev/null @@ -1,472 +0,0 @@ -# Server - API & Network Configuration - -Configuration for how Open Notebook's API and frontend communicate. - ---- - -## Most Important: API_URL - -**What it does:** Tells the frontend where to find the API. - -**Default behavior:** Auto-detected (usually works!) - -**When to set it:** Only if auto-detection doesn't work (reverse proxy, custom domain, etc.) - ---- - -## Auto-Detection (Default) - -Open Notebook automatically detects the API URL from your request: - -``` -You visit: http://localhost:8502 -It detects: http://localhost:5055 (same host, port 5055) - -You visit: http://myserver.com:8502 -It detects: http://myserver.com:5055 (same host, port 5055) - -You visit: https://myserver.com -It detects: https://myserver.com:5055 (same host, port 5055) -``` - -**This works because:** -- Frontend and API are usually on same host -- API is always on port 5055 -- System uses the hostname you're accessing from - ---- - -## When to Set API_URL - -Set `API_URL` only in these cases: - -### Case 1: Behind Reverse Proxy - -```env -# You access via: https://mynotebook.example.com -# But API is actually: https://api.example.com:5055 - -API_URL=https://api.example.com:5055 -``` - -### Case 2: Custom Domain - -```env -# You access via: https://notebook.mycompany.com -# API should be at: https://notebook.mycompany.com/api - -API_URL=https://notebook.mycompany.com -# System will auto-add /api to the end -``` - -### Case 3: Different Port - -```env -# You access via: http://localhost:3055 (custom port) -# API is on: http://localhost:3055 - -API_URL=http://localhost:3055 -``` - -### Case 4: Explicitly Disable Auto-Detection - -```env -# Force a specific URL (override auto-detection) -API_URL=http://192.168.1.100:5055 -``` - ---- - -## How to Configure - -### Method 1: .env File (Development) - -```env -# .env -API_URL=http://localhost:5055 -``` - -Restart services: -```bash -make api # or your restart command -``` - -### Method 2: docker.env (Docker) - -```env -# docker.env -API_URL=https://mynotebook.example.com -``` - -Restart: -```bash -docker compose restart frontend -``` - -### Method 3: Environment Variable - -```bash -export API_URL=https://mynotebook.example.com -docker compose up -``` - -### Method 4: docker-compose Override - -```yaml -services: - frontend: - environment: - - API_URL=https://mynotebook.example.com -``` - ---- - -## Port Configuration - -### Default Ports - -``` -Frontend: 3000 (dev) or 8502 (docker) -API: 5055 -SurrealDB: 8000 -``` - -### Changing Frontend Port - -Edit docker-compose.yml: - -```yaml -services: - frontend: - ports: - - "8001:8502" # Change from 8502 to 8001 -``` - -Access at: `http://localhost:8001` - -API auto-detects to: `http://localhost:5055` โœ“ - -### Changing API Port - -```yaml -services: - api: - ports: - - "5056:5055" # Change from 5055 to 5056 - environment: - - API_URL=http://localhost:5056 # Explicitly set -``` - -Access API directly: `http://localhost:5056/docs` - -### Changing SurrealDB Port - -```yaml -services: - surrealdb: - ports: - - "8001:8000" # Change from 8000 to 8001 - environment: - - SURREAL_URL=ws://surrealdb:8001/rpc # Update connection -``` - ---- - -## Timeouts - -How long to wait before giving up on operations. - -### API_CLIENT_TIMEOUT - -Controls how long the frontend waits for API responses. - -```env -# Default: 300 seconds (5 minutes) -API_CLIENT_TIMEOUT=300 -``` - -**When to increase:** -- Using Ollama on CPU (slow) -- Remote servers with high latency -- Large document processing -- Slow embeddings - -**Examples:** -```env -# Ollama on GPU -API_CLIENT_TIMEOUT=300 # Default is fine - -# Ollama on CPU -API_CLIENT_TIMEOUT=600 # 10 minutes - -# Very large documents -API_CLIENT_TIMEOUT=900 # 15 minutes -``` - -### ESPERANTO_LLM_TIMEOUT - -Timeout for individual LLM API calls (at the library level). - -```env -# Default: 60 seconds -ESPERANTO_LLM_TIMEOUT=60 -``` - -**When to increase:** -- Large model inference times -- Self-hosted LLMs on slow hardware -- Rate-limited APIs - -**Examples:** -```env -# OpenAI/Anthropic (fast) -ESPERANTO_LLM_TIMEOUT=60 # Default fine - -# Ollama large models on CPU -ESPERANTO_LLM_TIMEOUT=180 # 3 minutes - -# Self-hosted remote LLM -ESPERANTO_LLM_TIMEOUT=300 # 5 minutes -``` - -**Note:** Set `API_CLIENT_TIMEOUT` higher than `ESPERANTO_LLM_TIMEOUT` for proper error handling. - ---- - -## SSL/HTTPS - -### Basic Setup - -If using HTTPS (reverse proxy, custom domain): - -```env -API_URL=https://mynotebook.example.com -``` - -The system auto-detects protocol from your request (HTTP or HTTPS). - -### Self-Signed Certificates - -If using self-signed certs for local providers (Ollama, LM Studio behind proxy): - -#### Option 1: Disable Verification (Development Only) - -```env -# WARNING: Only for development/testing -# Exposes you to man-in-the-middle attacks -ESPERANTO_SSL_VERIFY=false -``` - -#### Option 2: Custom CA Bundle (Recommended) - -```env -# Point to your CA certificate -ESPERANTO_SSL_CA_BUNDLE=/path/to/ca-bundle.pem -``` - -To create CA bundle: -```bash -# Copy your certificate -cp your-cert.pem /path/to/ca-bundle.pem - -# Or combine multiple certs -cat cert1.pem cert2.pem > ca-bundle.pem -``` - ---- - -## Reverse Proxy Setup - -If you're running Open Notebook behind Nginx, Traefik, etc.: - -### Nginx Example - -```nginx -server { - server_name mynotebook.example.com; - listen 443 ssl; - - # Configure SSL... - ssl_certificate /path/to/cert.pem; - ssl_certificate_key /path/to/key.pem; - - # Frontend - location / { - proxy_pass http://localhost:8502; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } - - # API - location /api { - proxy_pass http://localhost:5055/api; - proxy_http_version 1.1; - } -} -``` - -Configuration: -```env -API_URL=https://mynotebook.example.com -``` - -### Cloudflare Reverse Proxy Example - -```env -# If using Cloudflare or similar -API_URL=https://mynotebook.example.com - -# You may need to preserve headers -# (Cloudflare usually handles this automatically) -``` - ---- - -## CORS Configuration - -Open Notebook automatically configures CORS to allow: -- Same domain access -- Localhost access (for development) -- Your specified API_URL - -**Usually no configuration needed.** - -If you get CORS errors: -1. Check `API_URL` matches your frontend URL -2. Verify no typos in domain names -3. Ensure HTTPS vs HTTP matches throughout - ---- - -## Health Check - -Test if API is running and accessible: - -```bash -# From your machine: -curl http://localhost:5055/health - -# Expected response: -# {"status":"ok"} - -# If behind reverse proxy: -curl https://mynotebook.example.com/health -``` - ---- - -## Testing Configuration - -### Step 1: Start Services - -```bash -docker compose up -d -``` - -### Step 2: Test Frontend - -```bash -# Open in browser -http://localhost:8502 # or your custom port -``` - -### Step 3: Test API - -```bash -# Direct API access -curl http://localhost:5055/docs - -# Should show Swagger UI -``` - -### Step 4: Test Connection - -``` -1. Open Open Notebook in browser -2. Go to create notebook -3. If works, configuration is correct! -``` - -### Step 5: Check Logs - -```bash -# If there's an issue -docker compose logs frontend | grep -i "api\|error" -docker compose logs api | grep -i "error" -``` - ---- - -## Troubleshooting - -### "Cannot connect to API" or "Unable to reach server" - -**Cause:** Frontend can't reach API - -**Checks:** -1. Is API running? `docker ps | grep api` -2. Is port 5055 exposed? `netstat -tlnp | grep 5055` -3. Is `API_URL` correct? Check browser console (F12) -4. Is frontend accessing the right domain? - -**Fix:** -```env -# Explicit API_URL -API_URL=http://localhost:5055 -# Restart -docker compose restart -``` - -### "Mixed content" or HTTPS warning - -**Cause:** Frontend is HTTPS but API is HTTP (or vice versa) - -**Fix:** -```env -# Make both HTTPS -API_URL=https://mynotebook.example.com - -# And ensure reverse proxy uses HTTPS -``` - -### Slow responses - -**Cause:** Timeout too short for your setup - -**Fix:** -```env -# Increase timeout -API_CLIENT_TIMEOUT=600 -# Restart -docker compose restart -``` - -### 404 on /api endpoints - -**Cause:** Reverse proxy not forwarding /api correctly - -**Fix (Nginx example):** -```nginx -location /api { - proxy_pass http://localhost:5055/api; # Keep /api in path -} -``` - ---- - -## Summary - -**For most setups:** -1. Leave `API_URL` unset (auto-detection works) -2. Keep default ports (3000/8502 frontend, 5055 API) -3. Only set `API_URL` if behind reverse proxy - -**Quick checklist:** -- [ ] Frontend can access API (test with curl) -- [ ] Ports are exposed correctly -- [ ] `API_URL` matches your frontend URL -- [ ] HTTPS/HTTP consistent throughout -- [ ] Timeouts set for your hardware speed - -If everything works, you're good! diff --git a/docs/7-DEVELOPMENT/api-reference.md b/docs/7-DEVELOPMENT/api-reference.md index 3a219f3..5cfa171 100644 --- a/docs/7-DEVELOPMENT/api-reference.md +++ b/docs/7-DEVELOPMENT/api-reference.md @@ -15,11 +15,11 @@ Complete REST API for Open Notebook. All endpoints are served from the API backe Simple password-based (development only): ```bash -curl http://localhost:5055/notebooks \ - -H "X-Password: your_password" +curl http://localhost:5055/api/notebooks \ + -H "Authorization: Bearer your_password" ``` -**โš ๏ธ Production**: Replace with OAuth/JWT. See CONFIGURATION.md for details. +**โš ๏ธ Production**: Replace with OAuth/JWT. See [Security Configuration](../5-CONFIGURATION/security.md) for details. ### 2. Base API Flow @@ -88,10 +88,12 @@ Instead of memorizing endpoints, use the interactive API docs: All requests require password header: ```bash -curl -H "X-Password: your_password" http://localhost:5055/notebooks +curl -H "Authorization: Bearer your_password" http://localhost:5055/api/notebooks ``` -Password configured via `ADMIN_PASSWORD` environment variable. +Password configured via `OPEN_NOTEBOOK_PASSWORD` environment variable. + +> **๐Ÿ“– See [Security Configuration](../5-CONFIGURATION/security.md)** for complete authentication setup, API examples, and production hardening. ### Production @@ -100,7 +102,7 @@ Password configured via `ADMIN_PASSWORD` environment variable. - JWT tokens - API keys -See CONFIGURATION.md for production setup. +See [Security Configuration](../5-CONFIGURATION/security.md) for production setup. --- @@ -202,10 +204,10 @@ All errors return JSON with status code: ## Production Considerations -- Replace password auth with OAuth/JWT +- Replace password auth with OAuth/JWT (see [Security](../5-CONFIGURATION/security.md)) - Add rate limiting via reverse proxy (Nginx, CloudFlare, Kong) - Enable CORS restrictions (currently allows all origins) -- Use HTTPS (reverse proxy + SSL cert) +- Use HTTPS via reverse proxy (see [Reverse Proxy](../5-CONFIGURATION/reverse-proxy.md)) - Set up API versioning strategy (currently implicit) -See CONFIGURATION.md for complete production setup. +See [Security Configuration](../5-CONFIGURATION/security.md) and [Reverse Proxy Setup](../5-CONFIGURATION/reverse-proxy.md) for complete production setup. diff --git a/docs/7-DEVELOPMENT/architecture.md b/docs/7-DEVELOPMENT/architecture.md index e5d7d8b..3ef2f8a 100644 --- a/docs/7-DEVELOPMENT/architecture.md +++ b/docs/7-DEVELOPMENT/architecture.md @@ -1,6 +1,43 @@ # Open Notebook Architecture -## Overview +## High-Level Overview + +Open Notebook follows a three-tier architecture with clear separation of concerns: + +``` +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ Your Browser โ”‚ +โ”‚ Access: http://your-server-ip:8502 โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ + โ–ผ + โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ Port 8502 โ”‚ โ† Next.js Frontend (what you see) + โ”‚ Frontend โ”‚ Also proxies API requests internally! + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ proxies /api/* requests โ†“ + โ–ผ + โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ Port 5055 โ”‚ โ† FastAPI Backend (handles requests) + โ”‚ API โ”‚ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ + โ–ผ + โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ SurrealDB โ”‚ โ† Database (internal, auto-configured) + โ”‚ (Port 8000) โ”‚ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ +``` + +**Key Points:** +- **v1.1+**: Next.js automatically proxies `/api/*` requests to the backend, simplifying reverse proxy setup +- Your browser loads the frontend from port 8502 +- The frontend needs to know where to find the API - when accessing remotely, set: `API_URL=http://your-server-ip:5055` +- **Behind reverse proxy?** You only need to proxy to port 8502 now! See [Reverse Proxy Configuration](../5-CONFIGURATION/reverse-proxy.md) + +--- + +## Detailed Architecture Open Notebook is built on a **three-tier, async-first architecture** designed for scalability, modularity, and multi-provider AI flexibility. The system separates concerns across frontend, API, and database layers, with LangGraph powering intelligent workflows and Esperanto enabling seamless integration with 8+ AI providers. diff --git a/justfile b/justfile deleted file mode 100644 index 96fe621..0000000 --- a/justfile +++ /dev/null @@ -1,5 +0,0 @@ - - -default: - just --list - \ No newline at end of file diff --git a/tests/test_models_api.py b/tests/test_models_api.py index 50fd229..60319ce 100644 --- a/tests/test_models_api.py +++ b/tests/test_models_api.py @@ -8,6 +8,7 @@ from fastapi.testclient import TestClient def client(): """Create test client after environment variables have been cleared by conftest.""" from api.main import app + return TestClient(app) @@ -17,48 +18,66 @@ class TestModelCreation: @pytest.mark.asyncio @patch("open_notebook.database.repository.repo_query") @patch("api.routers.models.Model.save") - async def test_create_duplicate_model_same_case(self, mock_save, mock_repo_query, client): + async def test_create_duplicate_model_same_case( + self, mock_save, mock_repo_query, client + ): """Test that creating a duplicate model with same case returns 400.""" # Mock repo_query to return a duplicate model - mock_repo_query.return_value = [{"id": "model:123", "name": "gpt-4", "provider": "openai", "type": "language"}] + mock_repo_query.return_value = [ + { + "id": "model:123", + "name": "gpt-4", + "provider": "openai", + "type": "language", + } + ] # Attempt to create duplicate response = client.post( "/api/models", - json={ - "name": "gpt-4", - "provider": "openai", - "type": "language" - } + json={"name": "gpt-4", "provider": "openai", "type": "language"}, ) assert response.status_code == 400 - assert response.json()["detail"] == "Model 'gpt-4' already exists for provider 'openai'" + assert ( + response.json()["detail"] + == "Model 'gpt-4' already exists for provider 'openai'" + ) @pytest.mark.asyncio @patch("open_notebook.database.repository.repo_query") @patch("api.routers.models.Model.save") - async def test_create_duplicate_model_different_case(self, mock_save, mock_repo_query, client): + async def test_create_duplicate_model_different_case( + self, mock_save, mock_repo_query, client + ): """Test that creating a duplicate model with different case returns 400.""" # Mock repo_query to return a duplicate model (case-insensitive match) - mock_repo_query.return_value = [{"id": "model:123", "name": "gpt-4", "provider": "openai", "type": "language"}] + mock_repo_query.return_value = [ + { + "id": "model:123", + "name": "gpt-4", + "provider": "openai", + "type": "language", + } + ] # Attempt to create duplicate with different case response = client.post( "/api/models", - json={ - "name": "GPT-4", - "provider": "OpenAI", - "type": "language" - } + json={"name": "GPT-4", "provider": "OpenAI", "type": "language"}, ) assert response.status_code == 400 - assert response.json()["detail"] == "Model 'GPT-4' already exists for provider 'OpenAI'" + assert ( + response.json()["detail"] + == "Model 'GPT-4' already exists for provider 'OpenAI'" + ) @pytest.mark.asyncio @patch("open_notebook.database.repository.repo_query") - async def test_create_same_model_name_different_provider(self, mock_repo_query, client): + async def test_create_same_model_name_different_provider( + self, mock_repo_query, client + ): """Test that creating a model with same name but different provider is allowed.""" from open_notebook.ai.models import Model @@ -66,15 +85,11 @@ class TestModelCreation: mock_repo_query.return_value = [] # Patch the save method on the Model class - with patch.object(Model, 'save', new_callable=AsyncMock) as mock_save: + with patch.object(Model, "save", new_callable=AsyncMock) as mock_save: # Attempt to create same model name with different provider (anthropic) response = client.post( "/api/models", - json={ - "name": "gpt-4", - "provider": "anthropic", - "type": "language" - } + json={"name": "gpt-4", "provider": "anthropic", "type": "language"}, ) # Should succeed because provider is different @@ -124,7 +139,9 @@ class TestModelsProviderAvailability: @patch("api.routers.models.os.environ.get") @patch("api.routers.models.AIFactory.get_available_providers") - def test_mode_specific_env_vars_llm_embedding(self, mock_esperanto, mock_env, client): + def test_mode_specific_env_vars_llm_embedding( + self, mock_esperanto, mock_env, client + ): """Test mode-specific env vars (LLM + EMBEDDING) enable only those 2 modes.""" # Mock environment: only LLM and EMBEDDING specific vars are set @@ -193,7 +210,9 @@ class TestModelsProviderAvailability: @patch("api.routers.models.os.environ.get") @patch("api.routers.models.AIFactory.get_available_providers") - def test_mixed_config_generic_and_mode_specific(self, mock_esperanto, mock_env, client): + def test_mixed_config_generic_and_mode_specific( + self, mock_esperanto, mock_env, client + ): """Test mixed config: generic + mode-specific (generic should enable all).""" # Mock environment: both generic and mode-specific vars are set