#4459: fix: enable image input for Kimi K2.5 and refresh stale config model definitions
agents
Cluster:
Kimi Model Enhancements
## Summary
Follow-up to #4407 (5e635c9) which added Kimi K2.5 to the synthetic catalog but declared it text-only.
- **Enable image input** for Kimi K2.5 in both the synthetic catalog (`synthetic-models.ts`) and the moonshot provider (`models-config.providers.ts`).
- **Fix stale config override bug** in `mergeProviderModels` (`models-config.ts`): onboarding bakes the full model catalog into `~/.openclaw/openclaw.json`, and the old merge logic let stale config definitions shadow code updates — so even after fixing the catalog in code, existing users would never see capability changes (like adding image support).
### What changed in the merge logic
**Before:** when both config file and code defined a model with the same ID, config always won — stale values for `input`, `reasoning`, `contextWindow`, `maxTokens` persisted forever.
**After:** code-defined capability fields override stale config entries, while user-specific fields (`cost`, `headers`, `compat`, `apiKey`) are preserved from config.
This affects all 7 providers that write model definitions during onboarding: synthetic, moonshot, kimi-code, xiaomi, venice, minimax, and qwen-portal.
### Testing
- Verified old merge produces `["text"]` (broken), new merge produces `["text", "image"]` (fixed)
- Verified user-specific fields (cost, apiKey) are preserved through merge
- Verified new model IDs from code are still appended
- End-to-end gateway test: stale `openclaw.json` + code fix → runtime `models.json` has correct `["text", "image"]`
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR enables image input for Kimi K2.5 in both the synthetic catalog and the Moonshot provider defaults, and updates model merging so code-defined capability fields refresh stale model definitions that were previously written into users’ `openclaw.json` during onboarding.
The core behavioral change is in `mergeProviderModels`, which now merges per-model entries by id: it preserves user-specific overrides from the config (e.g., cost/headers/compat/apiKey) while taking updated capability fields from the code-defined catalog, and still appends any new code-defined model ids not present in the config.
<h3>Confidence Score: 4/5</h3>
- This PR is generally safe to merge and addresses a real stale-config issue with low blast radius.
- Changes are localized to model catalog metadata and the merge behavior for provider model definitions; the new merge logic is straightforward and preserves explicit provider config while refreshing a fixed set of capability fields. Main remaining risk is schema drift: if additional capability fields exist or are added later, they may still remain stale, and the current override assigns `undefined` if an implicit model omits one of the refreshed fields.
- src/agents/models-config.ts
<!-- greptile_other_comments_section -->
<sub>(3/5) Reply to the agent's comments like "Can you suggest a fix for this @greptileai?" or ask follow-up questions!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#6960: feat: Add kimi-coding provider support
by YYW0228 · 2026-02-02
83.9%
#6454: fix: enable reasoning flag for Kimi K2.5 in Moonshot provider (#6451)
by coupclawbot · 2026-02-01
82.5%
#7570: fix: allow models from providers with auth profiles configured
by DonSqualo · 2026-02-03
82.1%
#5947: Feature/kimi reasoning support
by zzjj7000 · 2026-02-01
80.8%
#9024: Fix/Moonshot Provider Issue with kimi-k2-thinking Model Role Mappin...
by fotorpics · 2026-02-04
80.7%
#9739: #9291 fix(models): preserve existing models in models.json when mer...
by ximzzzzz · 2026-02-05
80.3%
#9822: fix: allow local/custom model providers for sub-agent inference
by stammtobias91 · 2026-02-05
79.7%
#11198: fix(models): strip @profile suffix from model selection
by mcaxtr · 2026-02-07
79.2%
#9583: fix(models): allow models in agents.defaults.models even if not in ...
by hotzen100 · 2026-02-05
78.4%
#14508: fix(models): allow forward-compat models in allowlist check
by jonisjongithub · 2026-02-12
78.4%