SIGN IN SIGN UP

feat: stale-while-revalidate file cache for model discovery (#19)

* feat: SWR file cache for model discovery

Cache discovered model entries under ~/.cache/opencode-litellm keyed
by baseURL hash. The config hook serves cached entries synchronously
so startup isn't blocked on the network after the first run; a
background refresh triggered on session.created revalidates the cache
for the next launch (stale-while-revalidate).

* refactor: call homedir() once in cacheDir()

* feat: expire model cache entries older than 7 days

Bound cache entries by savedAt so a permanently-gone proxy no longer
serves the same stale model list forever. Add readModelCacheSavedAt so
callers can throttle background refreshes on still-fresh caches.

* fix: write model cache atomically via temp file + rename

Prevents readers from observing a partially-written JSON file when two
OpenCode processes refresh the same baseURL concurrently.

* fix: clear discovery timeout timer to avoid keeping process alive

Extract a withTimeout helper that clears its setTimeout once the race
settles, so a completed discovery doesn't leave a pending timer holding
a short-lived process open.

* fix: throttle background cache refresh to a 5-minute interval

Skip revalidation when the cache's savedAt is within REFRESH_MIN_INTERVAL_MS
so a burst of session.created events can't generate repeated health checks
and discovery traffic. refreshInFlight still guards concurrent runs.

* refactor: track only plugin-injected model ids and use key presence

mergeModels now returns the ids it actually added, and injectedModelIds
stores exactly those instead of every provider key (which included
user-curated entries). Also use Object.hasOwn so entries that are null,
false, or 0 aren't treated as absent.
F
François committed
f0e41ae24e3a37b0f175b208a4c68a8939d99b4e
Parent: c9b9667
Committed by GitHub <noreply@github.com> on 8/26/2026, 2:47:16 PM