From e8277781299cd83cdc208e390a6a277e1489a528 Mon Sep 17 00:00:00 2001 From: Shakker Date: Sun, 26 Apr 2026 04:48:29 +0100 Subject: [PATCH] fix: keep provider index previews authoritative --- docs/plugins/manifest.md | 6 +++++- src/model-catalog/provider-index/normalize.test.ts | 10 ++++++++++ .../provider-index/openclaw-provider-index.ts | 11 +++++------ 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/docs/plugins/manifest.md b/docs/plugins/manifest.md index 28aa23573fc..d1e6a473ee8 100644 --- a/docs/plugins/manifest.md +++ b/docs/plugins/manifest.md @@ -740,7 +740,11 @@ Catalog authority order: 4. OpenClaw Provider Index preview rows. The Provider Index must not contain secrets, enabled state, runtime hooks, or -live account-specific model data. Providers with live `/models` discovery should +live account-specific model data. Its preview catalogs use the same +`modelCatalog` provider row shape as plugin manifests, but should stay limited +to stable display metadata unless runtime adapter fields such as `api`, +`baseUrl`, pricing, or compatibility flags are intentionally kept aligned with +the installed plugin manifest. Providers with live `/models` discovery should write refreshed rows through the explicit model catalog cache path instead of making normal listing or onboarding call provider APIs. diff --git a/src/model-catalog/provider-index/normalize.test.ts b/src/model-catalog/provider-index/normalize.test.ts index d60879ee45f..846274616b1 100644 --- a/src/model-catalog/provider-index/normalize.test.ts +++ b/src/model-catalog/provider-index/normalize.test.ts @@ -99,6 +99,8 @@ describe("OpenClaw provider index", () => { it("loads the bundled provider index without runtime plugin loading", () => { const index = loadOpenClawProviderIndex(); + expect(index.providers.moonshot?.previewCatalog).not.toHaveProperty("api"); + expect(index.providers.moonshot?.previewCatalog).not.toHaveProperty("baseUrl"); expect(index.providers.moonshot?.previewCatalog?.models).toEqual( expect.arrayContaining([ expect.objectContaining({ @@ -108,5 +110,13 @@ describe("OpenClaw provider index", () => { ]), ); expect(index.providers.deepseek?.plugin.id).toBe("deepseek"); + expect(index.providers.deepseek?.previewCatalog?.models).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + id: "deepseek-chat", + contextWindow: 131072, + }), + ]), + ); }); }); diff --git a/src/model-catalog/provider-index/openclaw-provider-index.ts b/src/model-catalog/provider-index/openclaw-provider-index.ts index 47c5357a063..493f451869b 100644 --- a/src/model-catalog/provider-index/openclaw-provider-index.ts +++ b/src/model-catalog/provider-index/openclaw-provider-index.ts @@ -3,6 +3,9 @@ import type { OpenClawProviderIndex } from "./types.js"; // OpenClaw-owned preview metadata for providers whose plugins may not be // installed yet. Installed plugin manifests remain authoritative; this index is // a fallback for installable-provider and pre-install model picker surfaces. +// Preview catalogs use the shared model catalog type, but intentionally keep to +// stable display fields unless runtime adapter metadata is kept in sync with +// the installed plugin manifest. export const OPENCLAW_PROVIDER_INDEX = { version: 1, providers: { @@ -15,8 +18,6 @@ export const OPENCLAW_PROVIDER_INDEX = { docs: "/providers/moonshot", categories: ["cloud", "llm"], previewCatalog: { - api: "openai-responses", - baseUrl: "https://api.moonshot.ai/v1", models: [ { id: "kimi-k2.6", @@ -36,21 +37,19 @@ export const OPENCLAW_PROVIDER_INDEX = { docs: "/providers/deepseek", categories: ["cloud", "llm"], previewCatalog: { - api: "openai-responses", - baseUrl: "https://api.deepseek.com/v1", models: [ { id: "deepseek-chat", name: "DeepSeek Chat", input: ["text"], - contextWindow: 64000, + contextWindow: 131072, }, { id: "deepseek-reasoner", name: "DeepSeek Reasoner", input: ["text"], reasoning: true, - contextWindow: 64000, + contextWindow: 131072, }, ], },