{"id":30020584,"url":"https://github.com/cdzombak/lychee-ai-organizer","last_synced_at":"2026-05-18T03:36:31.459Z","repository":{"id":306839347,"uuid":"1027376058","full_name":"cdzombak/lychee-ai-organizer","owner":"cdzombak","description":"Use local LLMs to organize your unsorted photos in Lychee","archived":false,"fork":false,"pushed_at":"2025-11-24T08:56:18.000Z","size":8400,"stargazers_count":11,"open_issues_count":2,"forks_count":2,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-12-06T11:09:55.115Z","etag":null,"topics":["lychee","ollama"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cdzombak.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-07-27T22:31:14.000Z","updated_at":"2025-11-11T07:07:28.000Z","dependencies_parsed_at":"2025-09-30T14:34:42.939Z","dependency_job_id":"c476a726-a026-4314-ac64-871f3d4c112d","html_url":"https://github.com/cdzombak/lychee-ai-organizer","commit_stats":null,"previous_names":["cdzombak/lychee-ai-organizer"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/cdzombak/lychee-ai-organizer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cdzombak%2Flychee-ai-organizer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cdzombak%2Flychee-ai-organizer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cdzombak%2Flychee-ai-organizer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cdzombak%2Flychee-ai-organizer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cdzombak","download_url":"https://codeload.github.com/cdzombak/lychee-ai-organizer/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cdzombak%2Flychee-ai-organizer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33163804,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-17T22:39:12.733Z","status":"online","status_checked_at":"2026-05-18T02:00:06.436Z","response_time":71,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["lychee","ollama"],"created_at":"2025-08-06T02:02:25.614Z","updated_at":"2026-05-18T03:36:31.453Z","avatar_url":"https://github.com/cdzombak.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AI-Powered Lychee Photo Organization Web Application\n\nThis application helps organize an existing [Lychee](https://github.com/LycheeOrg/Lychee) photo library into albums using artificial intelligence. It connects to a [Lychee](https://github.com/LycheeOrg/Lychee) photo database and uses AI to generate descriptions for photos and albums, then provides intelligent suggestions for organizing unsorted photos.\n\nThe application supports two AI providers:\n- **Ollama**: Local, open-source AI models (recommended for privacy and cost)\n- **OpenAI-compatible APIs**: Including OpenAI, Azure OpenAI, and other compatible services\n\n![screenshot](screenshot.png)\n\n## Configuration\n\n### Prerequisites\n\n- **Database**: Running Lychee photo database (MySQL, PostgreSQL, or SQLite)\n- **AI Provider**: Either:\n  - **Ollama**: Local instance with required models (recommended), OR\n  - **OpenAI-compatible API**: API endpoint and key\n\n### Database Setup\n\nAdd AI description columns to your Lychee database:\n\n#### MySQL\n```sql\n-- Add AI description columns to base_albums table\nALTER TABLE `base_albums`\nADD COLUMN `_ai_description` TEXT DEFAULT NULL,\nADD COLUMN `_ai_description_ts` TIMESTAMP NULL DEFAULT NULL;\n\n-- Add AI description columns to photos table\nALTER TABLE `photos`\nADD COLUMN `_ai_description` TEXT DEFAULT NULL,\nADD COLUMN `_ai_description_ts` TIMESTAMP NULL DEFAULT NULL;\n```\n\n#### PostgreSQL\n```sql\n-- Add AI description columns to base_albums table\nALTER TABLE base_albums\nADD COLUMN _ai_description TEXT DEFAULT NULL,\nADD COLUMN _ai_description_ts TIMESTAMP DEFAULT NULL;\n\n-- Add AI description columns to photos table\nALTER TABLE photos\nADD COLUMN _ai_description TEXT DEFAULT NULL,\nADD COLUMN _ai_description_ts TIMESTAMP DEFAULT NULL;\n```\n\n#### SQLite\n```sql\n-- Add AI description columns to base_albums table\nALTER TABLE base_albums\nADD COLUMN _ai_description TEXT DEFAULT NULL;\n\nALTER TABLE base_albums\nADD COLUMN _ai_description_ts DATETIME DEFAULT NULL;\n\n-- Add AI description columns to photos table\nALTER TABLE photos\nADD COLUMN _ai_description TEXT DEFAULT NULL;\n\nALTER TABLE photos\nADD COLUMN _ai_description_ts DATETIME DEFAULT NULL;\n```\n\n### AI Provider Setup\n\n#### Option 1: Ollama (Recommended)\n\nInstall Ollama and pull the recommended models:\n\n```bash\nollama pull qwen2.5vl:3b      # For image analysis\nollama pull qwen3:8b          # For description synthesis\n```\n\n#### Option 2: OpenAI-Compatible API\n\nYou can use OpenAI, Azure OpenAI, or any OpenAI-compatible API service. You'll need:\n- API endpoint URL\n- API key\n- Model names (e.g., `gpt-4o` for vision, `gpt-4o-mini` for text)\n\n### Application Configuration\n\n1. Copy the example configuration:\n   ```bash\n   cp config.example.json config.json\n   ```\n\n2. Edit `config.json`:\n\n   **With Ollama (using MySQL database):**\n   ```json\n   {\n     \"database\": {\n       \"type\": \"mysql\",\n       \"host\": \"localhost\",\n       \"port\": 3306,\n       \"username\": \"your_db_user\",\n       \"password\": \"your_db_password\",\n       \"database\": \"lychee\"\n     },\n     \"ai\": {\n       \"provider\": \"ollama\",\n       \"endpoint\": \"http://localhost:11434\",\n       \"image_analysis_model\": \"qwen2.5vl:3b\",\n       \"description_synthesis_model\": \"qwen3:8b\",\n       \"context_window\": 40960\n     },\n     \"server\": {\n       \"host\": \"localhost\",\n       \"port\": 8080\n     },\n     \"lychee\": {\n       \"base_url\": \"https://your-lychee-installation.com\"\n     },\n     \"albums\": {\n       \"blocklist\": [],\n       \"pinned_only\": false\n     }\n   }\n   ```\n\n   **With OpenAI (using MySQL database):**\n   ```json\n   {\n     \"database\": {\n       \"type\": \"mysql\",\n       \"host\": \"localhost\",\n       \"port\": 3306,\n       \"username\": \"your_db_user\",\n       \"password\": \"your_db_password\",\n       \"database\": \"lychee\"\n     },\n     \"ai\": {\n       \"provider\": \"openai\",\n       \"endpoint\": \"https://api.openai.com\",\n       \"api_key\": \"your-api-key-here\",\n       \"image_analysis_model\": \"gpt-4o\",\n       \"description_synthesis_model\": \"gpt-4o-mini\",\n       \"temperature\": 0.7\n     },\n     \"server\": {\n       \"host\": \"localhost\",\n       \"port\": 8080\n     },\n     \"lychee\": {\n       \"base_url\": \"https://your-lychee-installation.com\"\n     },\n   \"albums\": {\n     \"blocklist\": [],\n     \"pinned_only\": false\n   }\n  }\n  ```\n\n   Set `max_concurrent_requests` inside the `ai` block to control how many photo/album descriptions are generated in parallel (defaults to 4). Increase it only if your AI provider and database can comfortably handle the additional load.\n\n   **PostgreSQL Configuration Example:**\n   ```json\n   {\n     \"database\": {\n       \"type\": \"postgresql\",\n       \"host\": \"localhost\",\n       \"port\": 5432,\n       \"username\": \"your_db_user\",\n       \"password\": \"your_db_password\",\n       \"database\": \"lychee\"\n     },\n     \"ai\": {\n       \"provider\": \"ollama\",\n       \"endpoint\": \"http://localhost:11434\",\n       \"image_analysis_model\": \"qwen2.5vl:3b\",\n       \"description_synthesis_model\": \"qwen3:8b\",\n       \"context_window\": 40960\n     },\n     \"server\": {\n       \"host\": \"localhost\",\n       \"port\": 8080\n     },\n     \"lychee\": {\n       \"base_url\": \"https://your-lychee-installation.com\"\n     },\n     \"albums\": {\n       \"blocklist\": [],\n       \"pinned_only\": false\n     }\n   }\n   ```\n\n   **SQLite Configuration Example:**\n   ```json\n   {\n     \"database\": {\n       \"type\": \"sqlite\",\n       \"database\": \"/path/to/lychee.db\"\n     },\n     \"ai\": {\n       \"provider\": \"ollama\",\n       \"endpoint\": \"http://localhost:11434\",\n       \"image_analysis_model\": \"qwen2.5vl:3b\",\n       \"description_synthesis_model\": \"qwen3:8b\",\n       \"context_window\": 40960\n     },\n     \"server\": {\n       \"host\": \"localhost\",\n       \"port\": 8080\n     },\n     \"lychee\": {\n       \"base_url\": \"https://your-lychee-installation.com\"\n     },\n     \"albums\": {\n       \"blocklist\": [],\n       \"pinned_only\": false\n     }\n   }\n   ```\n\n#### Album Options\n\n- **Blocklist**: Exclude specific album IDs from AI processing and suggestions\n- **Pinned Only**: Restrict suggestions to pinned albums only (`is_pinned = true`)\n\n#### AI Configuration Options\n\n**Common to all providers:**\n- `provider`: Either `\"ollama\"` or `\"openai\"`\n- `endpoint`: API endpoint URL\n- `image_analysis_model`: Model name for analyzing images\n- `description_synthesis_model`: Model name for generating text descriptions\n- `temperature`: Sampling temperature (0.0-1.0, optional)\n- `top_p`: Top-p sampling (0.0-1.0, optional)\n\n**Ollama-specific:**\n- `context_window`: Maximum context length (recommended for `qwen3:8b`: 40960)\n- `options`: Additional Ollama parameters\n\n**OpenAI-specific:**\n- `api_key`: Your API key (required)\n\n#### Legacy Configuration\n\nThe old `\"ollama\"` configuration format is still supported for backward compatibility, but the new `\"ai\"` format is recommended.\n\n## Installation\n\n### macOS via Homebrew\n\n```shell\nbrew install cdzombak/oss/lychee-ai-organizer\n```\n\n### Debian via apt repository\n\n[Install my Debian repository](https://www.dzombak.com/blog/2025/06/updated-instructions-for-installing-my-debian-package-repositories/) if you haven't already:\n\n```shell\nsudo mkdir -p /etc/apt/keyrings\ncurl -fsSL https://dist.cdzombak.net/keys/dist-cdzombak-net.gpg -o /etc/apt/keyrings/dist-cdzombak-net.gpg\nsudo chmod 644 /etc/apt/keyrings/dist-cdzombak-net.gpg\nsudo mkdir -p /etc/apt/sources.list.d\nsudo curl -fsSL https://dist.cdzombak.net/cdzombak-oss.sources -o /etc/apt/sources.list.d/cdzombak-oss.sources\nsudo chmod 644 /etc/apt/sources.list.d/cdzombak-oss.sources\nsudo apt update\n```\n\nThen install `lychee-ai-organizer` via `apt-get`:\n\n```shell\nsudo apt-get install lychee-ai-organizer\n```\n\n### Manual installation from build artifacts\n\nPre-built binaries for Linux and macOS on various architectures are downloadable from each [GitHub Release](https://github.com/cdzombak/lychee-ai-organizer/releases). Debian packages for each release are available as well.\n\n### Build and install locally\n\n```shell\ngit clone https://github.com/cdzombak/lychee-ai-organizer.git\ncd lychee-ai-organizer\nmake build\n\ncp out/lychee-ai-organizer $INSTALL_DIR\n```\n\n## Running\n\n1. **Run** (if installed via package manager):\n   ```bash\n   lychee-ai-organizer -config config.json\n   ```\n\n2. **Run** (if built locally):\n   ```bash\n   ./out/lychee-ai-organizer -config config.json\n   ```\n\n3. **Access**: Open `http://localhost:8080` in your browser\n\n### Docker images\n\nDocker images are available for a variety of Linux architectures from [Docker Hub](https://hub.docker.com/r/cdzombak/lychee-ai-organizer) and [GHCR](https://github.com/cdzombak/lychee-ai-organizer/pkgs/container/lychee-ai-organizer). Images are based on the `scratch` image and are as small as possible.\n\nRun them via, for example:\n\n```shell\ndocker run --rm -v /path/to/config.json:/config.json cdzombak/lychee-ai-organizer:1 -config /config.json\ndocker run --rm -v /path/to/config.json:/config.json ghcr.io/cdzombak/lychee-ai-organizer:1 -config /config.json\n```\n\n## Usage\n\n### Initial Setup\n\n1. **Generate Photo Descriptions**: Click \"Describe Photos\" to analyze all unsorted photos\n2. **Generate Album Descriptions**: Click \"Describe All Albums\" to create album summaries\n3. **Monitor Progress**: Real-time updates show processing status\n\n**Important**: Always run \"Describe Photos\" first, then \"Describe All Albums\" for optimal results.\n\n### Organizing Photos\n\n1. **View Photos**: Unsorted photos appear in the bottom filmstrip\n2. **Navigate**: Click thumbnails or use arrow keys to browse photos\n3. **Get Suggestions**: Three AI-recommended albums appear at the top\n4. **Organize**: Click an album button to move the photo\n5. **Continue**: The interface automatically advances to the next photo\n\n### Additional Operations\n\n- **Retry Album Failures**: Reprocess any albums that failed during description generation\n- **Navigation**: Use Previous/Next buttons or arrow keys\n- **Photo Info**: View title, date, and AI-generated description for each photo\n\n## Troubleshooting\n\n### Common Issues\n\n**Database Connection Failed**\n- Verify database credentials and connectivity\n- Ensure schema modifications are applied\n- For SQLite: Ensure the database file path is correct and writable\n- For PostgreSQL: Ensure the database exists and user has proper permissions\n\n**Ollama Connection Failed**\n- Check Ollama is running on specified endpoint\n- Verify models are pulled and available\n\n**No Photos Found**\n- Ensure unsorted photos exist in database\n- Check `photo_album` table reflects current organization\n\n**Prompt Truncation**\n- Increase `context_window` to 32768 or higher\n- Monitor Ollama logs for truncation warnings\n\n### Performance\n\n- Image analysis requires significant computational resources\n- Processing time scales with photo count and model size\n- Consider using smaller models on limited hardware\n\n## API Reference\n\n- `GET /api/photos/unsorted` - List unsorted photos\n- `GET /api/photos/suggestions?photo_id=\u003cid\u003e` - Get album suggestions\n- `POST /api/photos/move` - Move photo to album\n- `POST /api/rescan` - Trigger AI processing\n- `WS /ws` - WebSocket for real-time updates\n\n## Security\n\n- Designed for local, personal use only\n- No authentication implemented\n- Secure your MySQL database appropriately\n- Do not expose to untrusted networks\n\n## License\n\nGNU General Public License v3.0; see [LICENSE](LICENSE) in this repository.\n\n## Author\n\n[Claude Code](https://www.anthropic.com/claude-code) wrote this code with management by Chris Dzombak ([dzombak.com](https://www.dzombak.com) / [github.com/cdzombak](https://www.github.com/cdzombak)).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcdzombak%2Flychee-ai-organizer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcdzombak%2Flychee-ai-organizer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcdzombak%2Flychee-ai-organizer/lists"}