Skip to content

fix(0.41.1): auto-update hook preserves [server] extras + kbagent version refreshes cache - #302

Merged
padak merged 1 commit into
mainfrom
feat/hotfix-0.41.1-auto-update
May 15, 2026
Merged

fix(0.41.1): auto-update hook preserves [server] extras + kbagent version refreshes cache#302
padak merged 1 commit into
mainfrom
feat/hotfix-0.41.1-auto-update

Conversation

@padak

@padak padak commented May 15, 2026

Copy link
Copy Markdown
Member

Summary

Two bugs combined to break kbagent serve --ui for users who installed with --with 'keboola-agent-cli[server]'. Symptoms observed in production today:

kbagent version                # shows "v0.41.0 available"
kbagent serve --ui             # auto-updates to v0.40.3 instead, then fails:
                               # ModuleNotFoundError: No module named 'fastapi'

Bug 1 — Startup auto-update hook drops [server] extras

The fix in v0.40.2 patched only the explicit kbagent update command (version_service._update_kbagent). The startup auto-update hook in auto_update._perform_update was left running the old bare uv tool install --upgrade git+... — no --with flag, so the FastAPI + uvicorn extras a user originally installed with --with 'keboola-agent-cli[server]' got silently dropped on every auto-update.

Fix: Refactored both paths to share build_kbagent_upgrade_command() in version_service.py. The helper probes importlib.util.find_spec('fastapi') (reliable proxy for "user originally installed with [server]") and pairs --with 'keboola-agent-cli[server]' with --force when extras are detected (--force is uv's documented way to combine --upgrade + --with since uv rejects them as a pair).

Bug 2 — kbagent version does not refresh the auto-update cache

get_versions() made a live GitHub round-trip but did NOT write the result back to ~/.config/keboola-agent-cli/version_cache.json. The 1-hour-TTL'd cache stayed pinned to whatever value the auto-update hook last wrote. The result: kbagent version correctly shows v0.41.0 available (live fetch), but a follow-up kbagent serve --ui on the same machine still auto-updates to whatever stale version the cache held (e.g. 0.40.3, written by an auto-update hook before 0.41.0 existed).

Combined with Bug 1, this produced the worst-case scenario: the version check says "new release available", serve --ui upgrades to a different older release, and fastapi disappears.

Fix: get_versions() now persists the freshly-fetched values via _write_cache (lazy-imported to avoid the auto_update ↔ version_service import cycle). Write failures are caught and logged at debug level so the version command never crashes on a read-only HOME / disk-full edge case.

Test plan

  • TestPerformUpdate.test_update_preserves_server_extras — when fastapi is importable, _perform_update argv contains --force --with 'keboola-agent-cli[server]', NOT --upgrade.
  • TestPerformUpdate.test_update_without_server_extras_uses_upgrade — when fastapi is NOT importable, argv contains plain --upgrade (no --with).
  • TestVersionService.test_persists_freshly_fetched_versions_to_cacheget_versions() calls _write_cache with the latest kbagent + MCP values.
  • TestVersionService.test_cache_write_failure_does_not_break_get_versions — cache write OSError does NOT propagate (best-effort).
  • make check: lint + format + skill + version + changelog + error-codes all clean.
  • Full test suite: 3313 passed, 7 skipped (0 failures).
  • Manual verification: cd worktree && pip install -e .[server] && python -c "from keboola_agent_cli.auto_update import _perform_update; from unittest.mock import patch; ..." — confirmed argv inspection matches the expected commands in both branches.

Diff stats

 9 files changed, 231 insertions(+), 80 deletions(-)
  • src/keboola_agent_cli/services/version_service.py: new module-level has_server_extras() + build_kbagent_upgrade_command(), removed the now-dead VersionService._has_server_extras static helper, refactored _update_kbagent to delegate.
  • src/keboola_agent_cli/auto_update.py: _perform_update delegates to build_kbagent_upgrade_command().
  • src/keboola_agent_cli/services/version_service.py: get_versions() persists cache.
  • tests/test_auto_update.py: 2 new tests pinning extras / no-extras branches.
  • tests/test_version_service.py: 2 new tests for cache write + failure handling.
  • src/keboola_agent_cli/changelog.py: 0.41.1 entry.
  • pyproject.toml, plugins/kbagent/.claude-plugin/plugin.json, .claude-plugin/marketplace.json: version bump.

…sion refreshes cache

Two bugs combined to break `kbagent serve --ui` for users who installed
with `--with 'keboola-agent-cli[server]'` and had a stale cache entry.

Bug 1: auto_update._perform_update dropped [server] extras
- The fix landed in v0.40.2 patched only `kbagent update`
  (version_service._update_kbagent), not the startup auto-update hook.
- `auto_update._perform_update` still ran a bare
  `uv tool install --upgrade git+...`, silently dropping fastapi+uvicorn.
- Refactored both paths to share `build_kbagent_upgrade_command()` so
  the install-spec construction (`--with`, `--force`, pip fallback)
  stays byte-for-byte consistent.

Bug 2: kbagent version did not refresh the auto-update cache
- `get_versions()` made a live GitHub round-trip but never wrote the
  result to ~/.config/keboola-agent-cli/version_cache.json.
- The 1h TTL'd cache stayed pinned to whatever the auto-update hook
  last wrote. Symptom: `kbagent version` shows "v0.41.0 available";
  follow-up `kbagent serve --ui` auto-updates to the cached older
  version (e.g. 0.40.3) and breaks (Bug 1 then drops extras on top).
- `get_versions()` now persists the freshly-fetched values via a
  lazy-imported `_write_cache` (lazy to avoid the auto_update <-->
  version_service import cycle). Write failures are caught and
  logged at debug level.

Tests:
- TestPerformUpdate.test_update_preserves_server_extras (extras path)
- TestPerformUpdate.test_update_without_server_extras_uses_upgrade
  (no-extras path)
- TestVersionService.test_persists_freshly_fetched_versions_to_cache
- TestVersionService.test_cache_write_failure_does_not_break_get_versions

Run: make check clean, 3313 tests pass.
@padak
padak merged commit b60e0a6 into main May 15, 2026
1 check passed
@padak
padak deleted the feat/hotfix-0.41.1-auto-update branch May 15, 2026 12:59
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.

1 participant