perf(modelscope): fetch a repository's model card once per run

A collection repository publishes many model files under a single source id,
but enrichment re-read the README and the model-detail payload for every one
of them: eight checkpoints meant sixteen HTTP requests, each detail payload
being 10-22 KB of JSON.

Add `ModelSourceCache`, created by `execute_skill()` for the duration of a
run and passed to the provider through a new optional `cache` argument on
`fetch_model_card_context()`. The agent caches the README (repository-wide
and provider-agnostic), and ModelScope caches its detail payload under a
provider-namespaced key.

Only successful reads are memoised, so a transient failure is still retried
for the next file, and the per-file selection is redone from the cached
payload so a checkpoint never inherits a sibling's example images. Nothing
is retained across runs — a model card can change at any time — and download
URLs are not routed through the cache.

Measured over the eight checkpoints of one ModelScope repository: 16
requests before, 2 after.

To keep the two concerns separable, `_build_card_context()` now turns a
detail payload into a `ModelCardContext` as a pure function.
This commit is contained in:
Will Miao
2026-09-14 21:24:57 +08:00
parent f0ee30fc68
commit e9e9ee20c6
7 changed files with 247 additions and 26 deletions
+7
View File
@@ -109,6 +109,13 @@ returns a `ModelCardContext`. Example images are matched to the model's
Sites with no such extras inherit an empty context, and the pipeline behaves
exactly as before.
The README and the repository metadata describe the whole repository, not one
file, so `execute_skill()` creates a `ModelSourceCache` for the duration of a
run and passes it down. Enriching the eight checkpoints of one ModelScope
repository costs two HTTP requests instead of sixteen; only the per-file
selection is redone for each file. Nothing is cached across runs, and download
URLs never go through it.
#### Deterministic data is applied whether or not an LLM is configured
`AgentService._load_source_card()` runs for every source-backed enrichment, and