Skip to content

Add modular extras and standalone CLI binary#76

Open
jhd3197 wants to merge 4 commits intomainfrom
dev
Open

Add modular extras and standalone CLI binary#76
jhd3197 wants to merge 4 commits intomainfrom
dev

Conversation

@jhd3197
Copy link
Owner

@jhd3197 jhd3197 commented Mar 4, 2026

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

  • Base pip install cachibot is now a lean ~36-package install with full agent, tool use, and sandboxed execution — no server, database, or embedding models
  • Mix and match extras: cachibot[server], cachibot[server,telegram], cachibot[knowledge], or cachibot[full] for everything
  • New cachi standalone binary on every release — one file, no runtime, available for Linux x64, macOS ARM64, and Windows x64
  • New cachibot-server-mini binary (Linux) for lightweight dashboard deployments on Raspberry Pi, VPS, or edge devices
  • CLI commands like server, diagnose, and repair now give a clear error message when server extras aren't installed instead of crashing with an import traceback
Technical changes
  • pyproject.toml: Split monolithic dependencies into core deps plus optional extras (server, knowledge, telegram, discord, slack, teams, platforms, full). Added pydantic>=2.9.0 to core deps since it's needed outside the server context
  • cachibot/cli.py: Wrapped all server-dependent imports (db_commands, api.server, auth_service, update_service, storage) in try/except ImportError blocks with user-friendly error messages pointing to the correct extras install command
  • cachibot/cli.py: Removed top-level import of cachibot.db_commands; db and setup-db sub-commands now register conditionally
  • cachibot/cli.py: Wrapped console.print call for better formatting of version/model output
  • desktop/pyinstaller-cli.py: New lean entry point for the CLI-only PyInstaller build — imports only cachibot.cli.app, no server dependencies
  • .github/workflows/publish.yml: Added build-cli job — builds cachi binary on Linux x64, macOS ARM64, and Windows x64 with smoke test (--help) and uploads archives to the GitHub release
  • .github/workflows/publish.yml: Added build-server-mini job — builds lightweight server binary (Linux only) with health-check smoke test and uploads to the release
  • .github/workflows/publish.yml: Existing build-server job 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 regenerates latest.yml with correct SHA-512 hash after code signing, fixing electron-updater auto-update verification
  • .github/workflows/publish.yml: update-release job now depends on build-cli and build-server-mini in addition to existing desktop and mobile builds
  • README.md: Rewrote "Why CachiBot?" section with "Lean by Default" positioning and extras table; added standalone binary download table; updated CLI usage to show cachi alias and split server-dependent commands; updated dev install to .[full,dev]; changed tagline from "Visual. Transparent. Secure." to "Lightweight. Modular. Armored."

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.
Copilot AI review requested due to automatic review settings March 4, 2026 22:56
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.
@jhd3197 jhd3197 changed the title Add CLI-only PyInstaller build and optional extras Add modular extras and standalone CLI binary Mar 4, 2026
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.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.toml to move server, knowledge, and platform dependencies into optional extras ([server], [knowledge], [telegram], etc.) with a [full] convenience bundle.
  • Added build-cli and build-server-mini CI jobs in the publish workflow, including archiving, uploading to GitHub Releases, and latest.yml regeneration 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
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
run: pyinstaller cachibot-cli.spec --clean
run: pyinstaller -n cachi --distpath dist/cachi -F -m cachi --clean

Copilot uses AI. Check for mistakes.
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
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
run: pyinstaller cachibot-server-mini.spec --clean
run: pyinstaller cachibot-server-mini.py --name cachibot-server-mini --clean

Copilot uses AI. Check for mistakes.
Comment on lines +355 to +359
if [[ "${{ matrix.archive_name }}" == *.zip ]]; then
${{ matrix.archive_cmd }} "${{ matrix.archive_name }}" cachi/
else
${{ matrix.archive_cmd }} "${{ matrix.archive_name }}" cachi/
fi
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
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/

Copilot uses AI. Check for mistakes.
Comment on lines +412 to +425
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"
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment on lines 37 to +43
dependencies = [
"prompture>=1.0.48",
"tukuy>=0.0.30",
"typer>=0.12.0",
"rich>=13.0.0",
# API server
"pydantic>=2.9.0",
]
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moving server dependencies out of the core dependencies into optional extras will break multiple existing files that aren't updated in this PR:

  1. CI workflow (.github/workflows/ci.yml): Installs with pip install -e ".[dev]", but the test suite (tests/conftest.py) imports sqlalchemy, httpx, and cachibot.storage.* at the top level — all of which now require the server extra. Should be updated to pip install -e ".[full,dev]".

  2. Dockerfile: Runs pip install --no-cache-dir . followed by CMD ["cachibot", "server"] — the server command requires server extras that are no longer installed. Should use pip install --no-cache-dir ".[server]" or ".[full]".

  3. CONTRIBUTING.md: Still references pip install -e ".[dev]" (line 36), inconsistent with the updated README which correctly says pip install -e ".[full,dev]".

Copilot uses AI. Check for mistakes.
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants