Skip to content

feat: evomem memory-engine auto-provisioning + setup integration#78

Merged
anvie merged 3 commits into
anvie:mainfrom
srflmr:feat/evomem-setup
Jun 24, 2026
Merged

feat: evomem memory-engine auto-provisioning + setup integration#78
anvie merged 3 commits into
anvie:mainfrom
srflmr:feat/evomem-setup

Conversation

@srflmr

@srflmr srflmr commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Auto-provision the evomem memory-engine binary and wire it into the setup surfaces. Two commits, kept separate for review.

Supersedes #76 — that PR bundled a Discord channel that shares no code with this change. Discord is now its own PR; this one is evomem + setup only.

1) feat(evomem): auto-provision the memory-engine binary

Problem. The memory engine defaults to evomem, but nothing installed the binary, so fresh installs silently fell back to FTS5; installer, doctor, and setup were inconsistent about it.

Change. backend/evomem_provision.py as the single source of truth: resolve the latest release via the GitHub API (EVOMEM_VERSION pins a tag), verify the download against the API-reported SHA-256, install atomically. On any failure (unsupported platform, network, checksum) it returns cleanly and the runtime keeps using FTS5. Wired through every surface: CLI evonic evomem install [--force]; doctor --fix (installs before judging the memory-engine check, via the single ensure_evomem() — no redundant directory stub); install.sh (best-effort, non-fatal); run_setup() logs whether evomem is ready or FTS5 will be used; .env.example documents EVONIC_MEMORY_ENGINE / EVOMEM_VERSION / EVOMEM_BINARY.

2) feat(setup): provision evomem during setup

Change. Hook provisioning into the existing setup surfaces — does not add a parallel wizard; builds on your evonic setup from b3bdd37:

  • CLI evonic setup: an evomem install step (interactive, default yes) after the super agent is created. Skipped under --non-interactive; install.sh provisions evomem directly and ensure_evomem() is idempotent.
  • Web setup wizard (templates/setup.html): an "Install evomem" checkbox (default on) + a Review row; routes/dashboard.py reads install_evomem and runs ensure_evomem() in the background restart thread so the download never blocks the HTTP response.

Why it's safe

  • Additive — new module + an opt-in step on existing commands. No models/ schema changes.
  • evomem provisioning is opt-in (default yes) and best-effort with a clean FTS5 fallback; no surface fails when the binary can't be installed.
  • Rebased on current main; reuses your setup_command() and backend/restart.py.

Test plan

  • test_evomem_provision green (network mocked).
  • python -m backend.evomem_provision downloads + installs evomem (best-effort, FTS5 fallback otherwise).
  • evonic setup, evonic evomem install, doctor --fix exercised cleanly. evonic setup --help confirms no subparser collision with the upstream wizard.

@anvie

anvie commented Jun 23, 2026

Copy link
Copy Markdown
Owner

Thanks for the PR! The single source of truth pattern for evomem binary provisioning is a great design choice, ensuring consistency across the CLI, web setup wizard, and installer. The implementation correctly handles idempotency, atomic installation, and integrity verification with thorough test coverage. One minor suggestion: consider downgrading the logging severity in _fail() from ERROR to WARNING for expected conditions like unsupported platforms to reduce production log noise. Overall, this looks great and is ready to merge.

srflmr added 3 commits June 24, 2026 06:17
The memory engine defaults to evomem, but nothing installed the binary, so
fresh installs silently fell back to FTS5. Installer, doctor, and setup were
also inconsistent about it.

Add backend/evomem_provision.py as the single source of truth: resolve the
latest release via the GitHub API (EVOMEM_VERSION pins a tag), verify the
download against the API-reported SHA-256, and install atomically. On any
failure (unsupported platform, network, checksum) it returns cleanly and the
runtime keeps using FTS5.

Wire it through every surface:
- CLI: `evonic evomem install [--force]`.
- doctor --fix: download/install the binary before judging section 10, so a
  single run reports the post-install state (was: only created the directory).
- install.sh: provision after dependency install (best-effort, non-fatal).
- setup: log whether evomem is ready or FTS5 will be used.
- .env.example: document EVONIC_MEMORY_ENGINE, EVOMEM_VERSION, EVOMEM_BINARY.

Add unit_tests/test_evomem_provision.py (network mocked): platform mapping,
idempotent skip, unsupported platform, checksum mismatch, missing digest, and
successful install.
Hook evomem provisioning into the existing setup surfaces rather than
adding a parallel wizard:

- CLI `evonic setup`: offer an evomem install step (interactive, default
  yes) after the super agent is created; skipped under --non-interactive
  since install.sh provisions evomem itself.
- Web setup wizard (templates/setup.html): an "Install evomem" checkbox
  (default on) plus a Review row. routes/dashboard.py reads install_evomem
  and runs ensure_evomem() in the background restart thread so the download
  never blocks the HTTP response.

Discord is intentionally absent from both wizards. Builds on the
evomem_provision single source of truth from the preceding commit.
…BINARY

Per review feedback, _fail() takes a level arg (default ERROR) and the
expected, non-actionable conditions (unsupported platform, no release
asset for this platform) log at WARNING to cut production noise; genuine
failures (network, missing digest, checksum mismatch, install error)
stay at ERROR.

Also align default_binary_path() with evomem_client._resolve_binary():
honour the EVOMEM_BINARY override so the provisioner installs exactly
where the runtime reads the binary, instead of always shared/bin/evomem.

Tests assert both severities and the env-override path.
@srflmr srflmr force-pushed the feat/evomem-setup branch from 83c9c47 to dcd1536 Compare June 23, 2026 23:22
@srflmr

srflmr commented Jun 23, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the review, @anvie!

Addressed the logging-severity suggestion: _fail() now takes a level arg (default ERROR). The expected, non-actionable conditions — unsupported platform and "no release asset for this platform" — log at WARNING to cut production noise, while genuine failures (network errors, missing sha256 digest, checksum mismatch, install error) stay at ERROR so real problems remain visible.

While in there I rebased onto the latest main and added one small related fix: default_binary_path() now honours the EVOMEM_BINARY override, mirroring evomem_client._resolve_binary(). Previously it always installed to shared/bin/evomem, so a custom EVOMEM_BINARY would be provisioned to a path the runtime never reads — now the provisioner writes exactly where the engine looks.

Tests assert both log severities and the env-override path; full suite green. Pushed as a separate commit on top so the changes are easy to diff.

@anvie anvie merged commit f723ab2 into anvie:main Jun 24, 2026
2 checks passed
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