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
@@ -104,8 +104,10 @@ class TestBuildPromptContext:
mock_fetch.assert_awaited_once_with("jj3550945163/Krea-2-LORA")
# The per-file lookup must receive the basename, not the full path.
mock_context.assert_awaited_once_with(
"jj3550945163/Krea-2-LORA", "krea.safetensors"
mock_context.assert_awaited_once()
assert mock_context.call_args.args == (
"jj3550945163/Krea-2-LORA",
"krea.safetensors",
)
assert context["source_platform"] == "modelscope"
assert context["source_id"] == "jj3550945163/Krea-2-LORA"
@@ -444,7 +446,8 @@ class TestLoadSourceCard:
},
)
mock_ctx.assert_awaited_once_with("u/r", "krea.safetensors")
mock_ctx.assert_awaited_once()
assert mock_ctx.call_args.args == ("u/r", "krea.safetensors")
assert context is card
assert variables["readme_content_full"] == "# card"
assert variables["source_description"] == "作者说明"