Conversation
Add a dedicated CLI-only PyInstaller build pipeline and make server/knowledge/platform deps optional. Updates .github/workflows/publish.yml to publish CLI binaries for Linux/macOS/Windows, archive and upload them to releases, regenerate latest.yml for Windows installer, and include the build-cli job in release dependencies. Modify cachibot/cli.py to lazily import server- and DB-related modules and show user-friendly errors when server extras are missing. Add desktop/pyinstaller-cli.py as a standalone entry point for PyInstaller. Rework pyproject.toml to move server, knowledge, and platform dependencies into optional extras and add a full extra so a minimal CLI install can be built without server deps. Also adjust install commands in the workflow to use the full extras where needed.
Split a long console.print invocation in cachibot/cli.py (reset_password) into multiple lines to improve readability and satisfy line-length formatting/linting. No functional change.
Include "cachibot[server]" in the dev extras and add "httpx>=0.27.0" to the dev dependency list in pyproject.toml. This enables server-related development workflows and provides an async HTTP client for tests and tooling.
There was a problem hiding this comment.
Pull request overview
This PR restructures CachiBot's dependency system to support a lightweight CLI-only installation by making server, knowledge, and platform dependencies optional extras. It adds a dedicated CLI-only PyInstaller build pipeline and a mini server build pipeline to the CI/CD workflow, updates the README to document the new modular installation approach, and modifies cachibot/cli.py to gracefully degrade when optional dependencies are not installed.
Changes:
- Restructured
pyproject.tomlto move server, knowledge, and platform dependencies into optional extras ([server],[knowledge],[telegram], etc.) with a[full]convenience bundle. - Added
build-cliandbuild-server-miniCI jobs in the publish workflow, including archiving, uploading to GitHub Releases, andlatest.ymlregeneration for Windows auto-updates. - Made server-dependent CLI commands (db, server, repair, diagnose) use lazy imports with user-friendly error messages when extras are missing.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
pyproject.toml |
Moved server/knowledge/platform deps to optional extras; added pydantic as core dep |
cachibot/cli.py |
Wrapped server-dependent imports in try/except ImportError with user-friendly messages |
desktop/pyinstaller-cli.py |
New standalone entry point for PyInstaller CLI-only builds |
.github/workflows/publish.yml |
Added build-cli and build-server-mini jobs, updated release notes and dependency chain, added latest.yml regeneration |
README.md |
Documented modular installation, standalone binaries, and updated contributing instructions |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| run: find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true | ||
|
|
||
| - name: Build CLI binary | ||
| run: pyinstaller cachibot-cli.spec --clean |
There was a problem hiding this comment.
The workflow references cachibot-cli.spec (line 339) and cachibot-server-mini.spec (line 403), but neither file exists in the repository. The build-cli and build-server-mini jobs will fail at the PyInstaller step. These spec files need to be created and included in this PR.
| run: pyinstaller cachibot-cli.spec --clean | |
| run: pyinstaller -n cachi --distpath dist/cachi -F -m cachi --clean |
| run: find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true | ||
|
|
||
| - name: Build mini server binary | ||
| run: pyinstaller cachibot-server-mini.spec --clean |
There was a problem hiding this comment.
The workflow references cachibot-server-mini.spec, but this file does not exist in the repository. This job will fail at the PyInstaller step. A spec file for the mini server build must be created and included in this PR.
| run: pyinstaller cachibot-server-mini.spec --clean | |
| run: pyinstaller cachibot-server-mini.py --name cachibot-server-mini --clean |
| if [[ "${{ matrix.archive_name }}" == *.zip ]]; then | ||
| ${{ matrix.archive_cmd }} "${{ matrix.archive_name }}" cachi/ | ||
| else | ||
| ${{ matrix.archive_cmd }} "${{ matrix.archive_name }}" cachi/ | ||
| fi |
There was a problem hiding this comment.
The if and else branches are identical — both execute ${{ matrix.archive_cmd }} "${{ matrix.archive_name }}" cachi/. The conditional is dead code. Since archive_cmd already varies per matrix entry (tar -czf vs zip -r), the if/else is unnecessary and should be simplified to a single unconditional command.
| if [[ "${{ matrix.archive_name }}" == *.zip ]]; then | |
| ${{ matrix.archive_cmd }} "${{ matrix.archive_name }}" cachi/ | |
| else | |
| ${{ matrix.archive_cmd }} "${{ matrix.archive_name }}" cachi/ | |
| fi | |
| ${{ matrix.archive_cmd }} "${{ matrix.archive_name }}" cachi/ |
| for i in $(seq 1 60); do | ||
| if curl -sf "http://127.0.0.1:$PORT/api/health" > /dev/null 2>&1; then | ||
| echo "Server healthy after ${i}s" | ||
| break | ||
| fi | ||
| if ! kill -0 $SERVER_PID 2>/dev/null; then | ||
| echo "ERROR: Server exited prematurely" | ||
| exit 1 | ||
| fi | ||
| sleep 1 | ||
| done | ||
|
|
||
| HEALTH=$(curl -sf "http://127.0.0.1:$PORT/api/health") | ||
| echo "Health: $HEALTH" |
There was a problem hiding this comment.
If the health endpoint never becomes healthy within 60 iterations, the for loop exits silently without an explicit failure. The subsequent curl -sf on line 424 will fail (thanks to set -e), but the error message will be confusing — it won't indicate a timeout. Consider adding an explicit failure after the loop, e.g., checking a variable set on success or failing with a clear "Timed out waiting for server" message.
| dependencies = [ | ||
| "prompture>=1.0.48", | ||
| "tukuy>=0.0.30", | ||
| "typer>=0.12.0", | ||
| "rich>=13.0.0", | ||
| # API server | ||
| "pydantic>=2.9.0", | ||
| ] |
There was a problem hiding this comment.
Moving server dependencies out of the core dependencies into optional extras will break multiple existing files that aren't updated in this PR:
-
CI workflow (
.github/workflows/ci.yml): Installs withpip install -e ".[dev]", but the test suite (tests/conftest.py) importssqlalchemy,httpx, andcachibot.storage.*at the top level — all of which now require theserverextra. Should be updated topip install -e ".[full,dev]". -
Dockerfile: Runs
pip install --no-cache-dir .followed byCMD ["cachibot", "server"]— theservercommand requires server extras that are no longer installed. Should usepip install --no-cache-dir ".[server]"or".[full]". -
CONTRIBUTING.md: Still references
pip install -e ".[dev]"(line 36), inconsistent with the updated README which correctly sayspip install -e ".[full,dev]".
Move pymupdf import into _extract_pdf to avoid requiring the optional dependency at module import time and only load it when extracting PDFs. Update pyproject dev extras from cachibot[server] to cachibot[full] so the development environment installs the full set of extras for testing and development.
CachiBot used to drag in every dependency whether you wanted a terminal agent or a multi-platform deployment — the digital equivalent of packing your entire wardrobe for a weekend trip. This PR splits the monolithic dependency list into composable extras (
server,knowledge,telegram,discord,slack,teams,full) and adds a standalone CLI binary built with PyInstaller for folks who don't want Python at all.Highlights
pip install cachibotis now a lean ~36-package install with full agent, tool use, and sandboxed execution — no server, database, or embedding modelscachibot[server],cachibot[server,telegram],cachibot[knowledge], orcachibot[full]for everythingcachistandalone binary on every release — one file, no runtime, available for Linux x64, macOS ARM64, and Windows x64cachibot-server-minibinary (Linux) for lightweight dashboard deployments on Raspberry Pi, VPS, or edge devicesserver,diagnose, andrepairnow give a clear error message when server extras aren't installed instead of crashing with an import tracebackTechnical changes
pyproject.toml: Split monolithicdependenciesinto core deps plus optional extras (server,knowledge,telegram,discord,slack,teams,platforms,full). Addedpydantic>=2.9.0to core deps since it's needed outside the server contextcachibot/cli.py: Wrapped all server-dependent imports (db_commands,api.server,auth_service,update_service,storage) intry/except ImportErrorblocks with user-friendly error messages pointing to the correct extras install commandcachibot/cli.py: Removed top-level import ofcachibot.db_commands;dbandsetup-dbsub-commands now register conditionallycachibot/cli.py: Wrappedconsole.printcall for better formatting of version/model outputdesktop/pyinstaller-cli.py: New lean entry point for the CLI-only PyInstaller build — imports onlycachibot.cli.app, no server dependencies.github/workflows/publish.yml: Addedbuild-clijob — buildscachibinary on Linux x64, macOS ARM64, and Windows x64 with smoke test (--help) and uploads archives to the GitHub release.github/workflows/publish.yml: Addedbuild-server-minijob — builds lightweight server binary (Linux only) with health-check smoke test and uploads to the release.github/workflows/publish.yml: Existingbuild-serverjob now installs.[full]instead of.to get all optional dependencies.github/workflows/publish.yml: Release body updated with download tables for CLI binaries and mini server.github/workflows/publish.yml: Windows desktop build now regenerateslatest.ymlwith correct SHA-512 hash after code signing, fixing electron-updater auto-update verification.github/workflows/publish.yml:update-releasejob now depends onbuild-cliandbuild-server-miniin addition to existing desktop and mobile buildsREADME.md: Rewrote "Why CachiBot?" section with "Lean by Default" positioning and extras table; added standalone binary download table; updated CLI usage to showcachialias and split server-dependent commands; updated dev install to.[full,dev]; changed tagline from "Visual. Transparent. Secure." to "Lightweight. Modular. Armored."