Skip to content

fix(cli): model-catalog cache — key by exact API key, shorten TTL, skip Ollama#6468

Open
joaomdmoura wants to merge 1 commit into
mainfrom
joaomdmoura/model-catalog-cache-fixes
Open

fix(cli): model-catalog cache — key by exact API key, shorten TTL, skip Ollama#6468
joaomdmoura wants to merge 1 commit into
mainfrom
joaomdmoura/model-catalog-cache-fixes

Conversation

@joaomdmoura

@joaomdmoura joaomdmoura commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

Follow-ups to the model-catalog cache from #6462. Two correctness bugs + a freshness tweak.

1. Cache key didn't distinguish which API key

The catalog cache key only encoded key-present vs absent (openai#key / openai#nokey). After a live fetch was cached, swapping to a different key for the same provider still hit the old entry and showed the previous account's model list (for up to the TTL).

Fix: key the cache by the exact API key via a short, non-reversible sha256 digest — openai#<digest> (never the raw key). A different key → different entry → refetch. Absent key stays #nokey.

2. Local (Ollama) lists were cached

Successful Ollama lists were written with the full dynamic TTL, and the cache was read before hitting /api/tags. The key only reflected the base URL, not installed models — so after you deleted a model locally, the picker could keep offering it until the entry expired.

Fix: never cache local providers. _is_cacheable() gates both cache read and write (Ollama excluded); /api/tags is fast, so the picker re-probes every call and always reflects what's installed.

3. Dynamic TTL shortened 6h → 5m

A stale list (new/removed models, account changes) is worse than a ~1s refetch; the cache only needs to spare repeated fetches within a wizard session.

Tests

  • distinct-key → separate cache entries (switching keys refetches)
  • cache key is a digest and never contains the raw key
  • Ollama is not cached: reflects a deletion between calls; never written to the cache file
  • dynamic entry older than the TTL is not served

ruff format --check + ruff check + mypy clean; test_model_catalog.py 39 passed.

Note

These are the two items you flagged from #6462. The sha256-digest approach keeps the raw API key out of the on-disk cache (~/.crewai/model_catalog_cache.json) — a truncated digest is non-reversible, so no secret is persisted.

🤖 Generated with Claude Code


Note

Low Risk
CLI-only wizard model picker caching; changes improve correctness and freshness without touching runtime crew execution or secrets beyond hashed cache keys.

Overview
Fixes model catalog caching in the crew-creation wizard so lists stay correct per account and for local Ollama.

Cache keys now use a short SHA-256 digest of the API key (provider#<digest>), not just key-present vs #nokey. Switching keys for the same provider refetches instead of reusing another account’s cached models. The raw key is never written to ~/.crewai/model_catalog_cache.json.

Ollama is excluded via _is_cacheable(): no read or write of the catalog cache, so every picker call hits /api/tags and reflects install/uninstall changes immediately.

Dynamic catalog TTL drops from 6h to 5m so stale vendor lists don’t linger; negative fallback TTL stays 5m.

Tests cover per-key cache separation, digest-only keys, Ollama non-caching, and expired dynamic entries.

Reviewed by Cursor Bugbot for commit 0690a7f. Bugbot is set up for automated code reviews on this repo. Configure here.

… Ollama

Follow-ups to #6462's caching:

1. Key the catalog cache by the exact API key (via a short, non-reversible
   sha256 digest — never the key itself), not just key-present vs absent.
   Switching to a different key for the same provider now misses the previous
   account's entry and refetches, instead of showing the old account's models.

2. Never cache local providers (Ollama). /api/tags is fast and installed
   models change out-of-band, so caching could keep offering a model the user
   just deleted until the entry expired. _is_cacheable() gates both cache read
   and write; the picker now re-probes every call and reflects what's installed.

3. Shorten the dynamic catalog TTL from 6h to 5m — a stale list (new/removed
   models, account changes) is worse than a ~1s refetch, and the cache only
   needs to spare repeated fetches within a wizard session.

Tests: distinct-key cache entries, digest never stores the raw key, Ollama not
cached (reflects deletions / never written), and dynamic TTL expiry.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RBYGqJHC2TMC6fonFziuuh
@github-actions github-actions Bot added the size/M label Jul 7, 2026
@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0ea3c42d-b8a2-44bc-9dca-704a11aeb276

📥 Commits

Reviewing files that changed from the base of the PR and between 799ab0f and 0690a7f.

📒 Files selected for processing (2)
  • lib/cli/src/crewai_cli/model_catalog.py
  • lib/cli/tests/test_model_catalog.py

📝 Walkthrough

Walkthrough

The dynamic model catalog's TTL was reduced to 300 seconds, and cache keying was reworked to hash provider API keys (truncated SHA-256) instead of special-casing Ollama. A new _is_cacheable helper gates cache reads/writes, and tests were updated to cover Ollama exclusion, key isolation, digest-only keys, and TTL expiry.

Changes

Model Catalog Cache Rework

Layer / File(s) Summary
TTL constant and hashing setup
lib/cli/src/crewai_cli/model_catalog.py
Adds hashlib import and reduces _CATALOG_TTL from 6 hours to 300 seconds.
Cacheability gating and hashed cache key
lib/cli/src/crewai_cli/model_catalog.py
Removes the inline ollama check in get_provider_models, adds _is_cacheable, rewrites _cache_key to hash API keys, and updates _read_catalog_cache/_write_catalog_cache to early-return for non-cacheable providers.
Cache behavior tests
lib/cli/tests/test_model_catalog.py
Adds tests for Ollama not being served stale or written to cache, per-API-key cache isolation, digest-only cache keys, and TTL-based expiry of stale entries.

Suggested reviewers: lorenzejay

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the cache key, TTL, and Ollama caching changes.
Description check ✅ Passed The description clearly matches the cache key, Ollama, and TTL updates in the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch joaomdmoura/model-catalog-cache-fixes

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant