refactor: move model catalog normalization into core package

Move model catalog normalization and package-owned catalog schema/types into model-catalog-core while keeping public plugin SDK model catalog declarations on the existing SDK surface. Verified focused tests, package-boundary compile, full build, changed gate, declaration leak grep, CI, and autoreview.
This commit is contained in:
Peter Steinberger
2026-05-30 20:51:11 +01:00
committed by GitHub
parent 961691def2
commit 5891cfec3e
27 changed files with 371 additions and 66 deletions

View File

@@ -111,6 +111,12 @@
"@openclaw/model-catalog-core/model-catalog-refs": [
"../dist/plugin-sdk/packages/model-catalog-core/src/model-catalog-refs.d.ts"
],
"@openclaw/model-catalog-core/model-catalog-normalize": [
"../dist/plugin-sdk/packages/model-catalog-core/src/model-catalog-normalize.d.ts"
],
"@openclaw/model-catalog-core/model-catalog-types": [
"../dist/plugin-sdk/packages/model-catalog-core/src/model-catalog-types.d.ts"
],
"@openclaw/model-catalog-core/provider-id": [
"../dist/plugin-sdk/packages/model-catalog-core/src/provider-id.d.ts"
],

View File

@@ -120,6 +120,12 @@
"@openclaw/model-catalog-core/model-catalog-refs": [
"../../dist/plugin-sdk/packages/model-catalog-core/src/model-catalog-refs.d.ts"
],
"@openclaw/model-catalog-core/model-catalog-normalize": [
"../../dist/plugin-sdk/packages/model-catalog-core/src/model-catalog-normalize.d.ts"
],
"@openclaw/model-catalog-core/model-catalog-types": [
"../../dist/plugin-sdk/packages/model-catalog-core/src/model-catalog-types.d.ts"
],
"@openclaw/model-catalog-core/provider-id": [
"../../dist/plugin-sdk/packages/model-catalog-core/src/provider-id.d.ts"
],

View File

@@ -24,6 +24,16 @@
"import": "./dist/model-catalog-refs.mjs",
"default": "./dist/model-catalog-refs.mjs"
},
"./model-catalog-normalize": {
"types": "./dist/model-catalog-normalize.d.mts",
"import": "./dist/model-catalog-normalize.mjs",
"default": "./dist/model-catalog-normalize.mjs"
},
"./model-catalog-types": {
"types": "./dist/model-catalog-types.d.mts",
"import": "./dist/model-catalog-types.mjs",
"default": "./dist/model-catalog-types.mjs"
},
"./provider-id": {
"types": "./dist/provider-id.d.mts",
"import": "./dist/provider-id.mjs",

View File

@@ -1,5 +1,7 @@
export * from "./configured-model-refs.js";
export * from "./model-catalog-normalize.js";
export * from "./model-catalog-refs.js";
export * from "./model-catalog-types.js";
export * from "./provider-id.js";
export * from "./provider-model-id-normalization.js";
export * from "./provider-model-id-normalize.js";

View File

@@ -1,9 +1,6 @@
import {
buildModelCatalogMergeKey,
buildModelCatalogRef,
} from "@openclaw/model-catalog-core/model-catalog-refs";
import { describe, expect, it } from "vitest";
import { normalizeModelCatalog, normalizeModelCatalogRows } from "./index.js";
import { buildModelCatalogMergeKey, buildModelCatalogRef } from "./model-catalog-refs.js";
describe("model catalog normalization", () => {
it("normalizes catalog ownership, aliases, suppressions, and row fields", () => {

View File

@@ -2,44 +2,66 @@ import {
buildModelCatalogMergeKey,
buildModelCatalogRef,
normalizeModelCatalogProviderId,
} from "@openclaw/model-catalog-core/model-catalog-refs";
} from "./model-catalog-refs.js";
import {
MODEL_APIS,
isModelThinkingFormat,
type ModelApi,
type ModelCompatConfig,
type ModelImageInputConfig,
type ModelMediaInputConfig,
} from "../config/types.models.js";
import { isBlockedObjectKey } from "../infra/prototype-keys.js";
import { normalizeOptionalString } from "../shared/string-coerce.js";
import {
normalizeOptionalTrimmedStringList,
normalizeTrimmedStringList,
} from "../shared/string-normalization.js";
import { isRecord } from "../utils.js";
import type {
ModelCatalog,
ModelCatalogAlias,
ModelCatalogCost,
ModelCatalogDiscovery,
ModelCatalogInput,
ModelCatalogModel,
ModelCatalogProvider,
ModelCatalogSource,
ModelCatalogStatus,
ModelCatalogSuppression,
ModelCatalogTieredCost,
NormalizedModelCatalogRow,
} from "./types.js";
MODEL_CATALOG_APIS,
isModelCatalogThinkingFormat,
type ModelCatalog,
type ModelCatalogAlias,
type ModelCatalogApi,
type ModelCatalogCompatConfig,
type ModelCatalogCost,
type ModelCatalogDiscovery,
type ModelCatalogImageInputConfig,
type ModelCatalogInput,
type ModelCatalogMediaInputConfig,
type ModelCatalogModel,
type ModelCatalogProvider,
type ModelCatalogSource,
type ModelCatalogStatus,
type ModelCatalogSuppression,
type ModelCatalogTieredCost,
type NormalizedModelCatalogRow,
} from "./model-catalog-types.js";
const MODEL_CATALOG_INPUTS = new Set(["text", "image", "document"]);
const MODEL_CATALOG_DISCOVERY_MODES = new Set(["static", "refreshable", "runtime"]);
const MODEL_CATALOG_STATUSES = new Set(["available", "preview", "deprecated", "disabled"]);
const MODEL_CATALOG_APIS = new Set<string>(MODEL_APIS);
const MODEL_CATALOG_API_SET = new Set<string>(MODEL_CATALOG_APIS);
const DEFAULT_MODEL_INPUT: ModelCatalogInput[] = ["text"];
const DEFAULT_MODEL_STATUS: ModelCatalogStatus = "available";
function isRecord(value: unknown): value is Record<string, unknown> {
return typeof value === "object" && value !== null && !Array.isArray(value);
}
function isBlockedObjectKey(key: string): boolean {
return key === "__proto__" || key === "prototype" || key === "constructor";
}
function normalizeOptionalString(value: unknown): string | undefined {
if (typeof value !== "string") {
return undefined;
}
const trimmed = value.trim();
return trimmed ? trimmed : undefined;
}
function normalizeTrimmedStringList(value: unknown): string[] {
if (!Array.isArray(value)) {
return [];
}
return value.flatMap((entry) => {
const normalized = normalizeOptionalString(entry);
return normalized ? [normalized] : [];
});
}
function normalizeOptionalTrimmedStringList(value: unknown): string[] | undefined {
const normalized = normalizeTrimmedStringList(value);
return normalized.length > 0 ? normalized : undefined;
}
function normalizeSafeRecordKey(value: unknown): string {
const key = normalizeOptionalString(value) ?? "";
return key && !isBlockedObjectKey(key) ? key : "";
@@ -81,9 +103,9 @@ function mergeStringMaps(
return { ...base, ...override };
}
function normalizeModelCatalogApi(value: unknown): ModelApi | undefined {
function normalizeModelCatalogApi(value: unknown): ModelCatalogApi | undefined {
const api = normalizeOptionalString(value) ?? "";
return MODEL_CATALOG_APIS.has(api) ? (api as ModelApi) : undefined;
return MODEL_CATALOG_API_SET.has(api) ? (api as ModelCatalogApi) : undefined;
}
function normalizeModelCatalogInputs(value: unknown): ModelCatalogInput[] | undefined {
@@ -165,7 +187,7 @@ function normalizeModelCatalogCost(value: unknown): ModelCatalogCost | undefined
return Object.keys(cost).length > 0 ? cost : undefined;
}
function normalizeModelCatalogCompat(value: unknown): ModelCompatConfig | undefined {
function normalizeModelCatalogCompat(value: unknown): ModelCatalogCompatConfig | undefined {
if (!isRecord(value)) {
return undefined;
}
@@ -230,11 +252,11 @@ function normalizeModelCatalogCompat(value: unknown): ModelCompatConfig | undefi
}
const thinkingFormat = normalizeOptionalString(value.thinkingFormat) ?? "";
if (isModelThinkingFormat(thinkingFormat)) {
if (isModelCatalogThinkingFormat(thinkingFormat)) {
compat.thinkingFormat = thinkingFormat;
}
return Object.keys(compat).length > 0 ? (compat as ModelCompatConfig) : undefined;
return Object.keys(compat).length > 0 ? (compat as ModelCatalogCompatConfig) : undefined;
}
function normalizeModelCatalogStatus(value: unknown): ModelCatalogStatus | undefined {
@@ -242,7 +264,9 @@ function normalizeModelCatalogStatus(value: unknown): ModelCatalogStatus | undef
return MODEL_CATALOG_STATUSES.has(status) ? (status as ModelCatalogStatus) : undefined;
}
function normalizeModelCatalogImageTokenMode(value: unknown): ModelImageInputConfig["tokenMode"] {
function normalizeModelCatalogImageTokenMode(
value: unknown,
): ModelCatalogImageInputConfig["tokenMode"] {
const tokenMode = normalizeOptionalString(value) ?? "";
if (tokenMode === "tile" || tokenMode === "detail" || tokenMode === "provider") {
return tokenMode;
@@ -250,7 +274,7 @@ function normalizeModelCatalogImageTokenMode(value: unknown): ModelImageInputCon
return undefined;
}
function normalizeModelCatalogMediaInput(value: unknown): ModelMediaInputConfig | undefined {
function normalizeModelCatalogMediaInput(value: unknown): ModelCatalogMediaInputConfig | undefined {
if (!isRecord(value) || !isRecord(value.image)) {
return undefined;
}

View File

@@ -0,0 +1,204 @@
export const MODEL_CATALOG_APIS = [
"openai-completions",
"openai-responses",
"openai-codex-responses",
"anthropic-messages",
"google-generative-ai",
"google-vertex",
"github-copilot",
"bedrock-converse-stream",
"ollama",
"azure-openai-responses",
] as const;
export type ModelCatalogApi = (typeof MODEL_CATALOG_APIS)[number];
export const MODEL_CATALOG_THINKING_FORMATS = [
"openai",
"openrouter",
"deepseek",
"together",
"qwen",
"qwen-chat-template",
"zai",
] as const;
export type ModelCatalogThinkingFormat = (typeof MODEL_CATALOG_THINKING_FORMATS)[number];
export function isModelCatalogThinkingFormat(value: string): value is ModelCatalogThinkingFormat {
return (MODEL_CATALOG_THINKING_FORMATS as readonly string[]).includes(value);
}
export type ModelCatalogCompatConfig = {
supportsStore?: boolean;
supportsDeveloperRole?: boolean;
supportsReasoningEffort?: boolean;
supportsUsageInStreaming?: boolean;
supportsStrictMode?: boolean;
maxTokensField?: "max_completion_tokens" | "max_tokens";
requiresToolResultName?: boolean;
requiresAssistantAfterToolResult?: boolean;
requiresThinkingAsText?: boolean;
supportsPromptCacheKey?: boolean;
supportsTools?: boolean;
requiresStringContent?: boolean;
strictMessageKeys?: boolean;
toolSchemaProfile?: string;
unsupportedToolSchemaKeywords?: string[];
nativeWebSearchTool?: boolean;
toolCallArgumentsEncoding?: string;
requiresMistralToolIds?: boolean;
requiresOpenAiAnthropicToolPayload?: boolean;
thinkingFormat?: ModelCatalogThinkingFormat;
supportedReasoningEfforts?: string[];
reasoningEffortMap?: Record<string, string>;
visibleReasoningDetailTypes?: string[];
};
export type ModelCatalogImageInputConfig = {
maxBytes?: number;
maxPixels?: number;
maxSidePx?: number;
preferredSidePx?: number;
tokenMode?: "tile" | "detail" | "provider";
};
export type ModelCatalogMediaInputConfig = {
image?: ModelCatalogImageInputConfig;
};
export type ModelCatalogInput = "text" | "image" | "document";
export type ModelCatalogDiscovery = "static" | "refreshable" | "runtime";
export type ModelCatalogStatus = "available" | "preview" | "deprecated" | "disabled";
export type ModelCatalogSource =
| "manifest"
| "provider-index"
| "cache"
| "config"
| "runtime-refresh";
export type UnifiedModelCatalogKind =
| "text"
| "voice"
| "image_generation"
| "video_generation"
| "music_generation";
export type UnifiedModelCatalogSource =
| "manifest"
| "provider-index"
| "static"
| "live"
| "cache"
| "configured"
| "runtime-refresh";
export type UnifiedModelCatalogEntry<TCapabilities = unknown> = {
kind: UnifiedModelCatalogKind;
provider: string;
model: string;
label?: string;
source: UnifiedModelCatalogSource;
default?: boolean;
configured?: boolean;
capabilities?: TCapabilities;
modes?: readonly string[];
authEnvVars?: readonly string[];
docsPath?: string;
fetchedAt?: number;
expiresAt?: number;
warnings?: readonly string[];
};
export type ModelCatalogTieredCost = {
input: number;
output: number;
cacheRead: number;
cacheWrite: number;
range: [number, number] | [number];
};
export type ModelCatalogCost = {
input?: number;
output?: number;
cacheRead?: number;
cacheWrite?: number;
tieredPricing?: ModelCatalogTieredCost[];
};
export type ModelCatalogModel = {
id: string;
name?: string;
api?: ModelCatalogApi;
baseUrl?: string;
headers?: Record<string, string>;
input?: ModelCatalogInput[];
reasoning?: boolean;
contextWindow?: number;
contextTokens?: number;
maxTokens?: number;
cost?: ModelCatalogCost;
compat?: ModelCatalogCompatConfig;
mediaInput?: ModelCatalogMediaInputConfig;
status?: ModelCatalogStatus;
statusReason?: string;
replaces?: string[];
replacedBy?: string;
tags?: string[];
};
export type ModelCatalogProvider = {
baseUrl?: string;
api?: ModelCatalogApi;
headers?: Record<string, string>;
models: ModelCatalogModel[];
};
export type ModelCatalogAlias = {
provider: string;
api?: ModelCatalogApi;
baseUrl?: string;
};
export type ModelCatalogSuppression = {
provider: string;
model: string;
reason?: string;
when?: {
baseUrlHosts?: string[];
providerConfigApiIn?: string[];
};
};
export type ModelCatalog = {
providers?: Record<string, ModelCatalogProvider>;
aliases?: Record<string, ModelCatalogAlias>;
suppressions?: ModelCatalogSuppression[];
discovery?: Record<string, ModelCatalogDiscovery>;
runtimeAugment?: boolean;
};
export type NormalizedModelCatalogRow = {
provider: string;
id: string;
ref: string;
mergeKey: string;
name: string;
source: ModelCatalogSource;
input: ModelCatalogInput[];
reasoning: boolean;
status: ModelCatalogStatus;
api?: ModelCatalogApi;
baseUrl?: string;
headers?: Record<string, string>;
contextWindow?: number;
contextTokens?: number;
maxTokens?: number;
cost?: ModelCatalogCost;
compat?: ModelCatalogCompatConfig;
mediaInput?: ModelCatalogMediaInputConfig;
statusReason?: string;
replaces?: string[];
replacedBy?: string;
tags?: string[];
};

View File

@@ -66,6 +66,12 @@ export const EXTENSION_PACKAGE_BOUNDARY_BASE_PATHS = {
"@openclaw/model-catalog-core/model-catalog-refs": [
"../dist/plugin-sdk/packages/model-catalog-core/src/model-catalog-refs.d.ts",
],
"@openclaw/model-catalog-core/model-catalog-normalize": [
"../dist/plugin-sdk/packages/model-catalog-core/src/model-catalog-normalize.d.ts",
],
"@openclaw/model-catalog-core/model-catalog-types": [
"../dist/plugin-sdk/packages/model-catalog-core/src/model-catalog-types.d.ts",
],
"@openclaw/model-catalog-core/provider-id": [
"../dist/plugin-sdk/packages/model-catalog-core/src/provider-id.d.ts",
],

View File

@@ -70,7 +70,9 @@ const ROOT_DTS_REQUIRED_OUTPUTS = [
"dist/plugin-sdk/packages/terminal-core/src/terminal-link.d.ts",
"dist/plugin-sdk/packages/terminal-core/src/theme.d.ts",
"dist/plugin-sdk/packages/model-catalog-core/src/configured-model-refs.d.ts",
"dist/plugin-sdk/packages/model-catalog-core/src/model-catalog-normalize.d.ts",
"dist/plugin-sdk/packages/model-catalog-core/src/model-catalog-refs.d.ts",
"dist/plugin-sdk/packages/model-catalog-core/src/model-catalog-types.d.ts",
"dist/plugin-sdk/packages/model-catalog-core/src/provider-id.d.ts",
"dist/plugin-sdk/packages/model-catalog-core/src/provider-model-id-normalization.d.ts",
"dist/plugin-sdk/packages/model-catalog-core/src/provider-model-id-normalize.d.ts",
@@ -97,7 +99,9 @@ const PACKAGE_DTS_REQUIRED_OUTPUTS = [
"packages/plugin-sdk/dist/packages/media-generation-core/src/model-ref.d.ts",
"packages/plugin-sdk/dist/packages/media-generation-core/src/normalization.d.ts",
"packages/plugin-sdk/dist/packages/model-catalog-core/src/configured-model-refs.d.ts",
"packages/plugin-sdk/dist/packages/model-catalog-core/src/model-catalog-normalize.d.ts",
"packages/plugin-sdk/dist/packages/model-catalog-core/src/model-catalog-refs.d.ts",
"packages/plugin-sdk/dist/packages/model-catalog-core/src/model-catalog-types.d.ts",
"packages/plugin-sdk/dist/packages/model-catalog-core/src/provider-id.d.ts",
"packages/plugin-sdk/dist/packages/model-catalog-core/src/provider-model-id-normalization.d.ts",
"packages/plugin-sdk/dist/packages/model-catalog-core/src/provider-model-id-normalize.d.ts",

View File

@@ -1,6 +1,6 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../config/types.openclaw.js";
import type { NormalizedModelCatalogRow } from "../model-catalog/index.js";
import type { NormalizedModelCatalogRow } from "../model-catalog/types.js";
import type { RuntimeEnv } from "../runtime.js";
import type { WizardPrompter } from "../wizard/prompts.js";

View File

@@ -2,7 +2,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { testing as cliBackendsTesting } from "../agents/cli-backends.js";
import type { ModelCatalogEntry } from "../agents/model-catalog.js";
import type { OpenClawConfig } from "../config/config.js";
import type { NormalizedModelCatalogRow } from "../model-catalog/index.js";
import type { NormalizedModelCatalogRow } from "../model-catalog/types.js";
import {
applyModelAllowlist,
applyModelFallbacksFromSelection,

View File

@@ -1,7 +1,7 @@
import { normalizeModelCatalogProviderId } from "@openclaw/model-catalog-core/model-catalog-refs";
import type { OpenClawConfig } from "../../config/types.openclaw.js";
import { planManifestModelCatalogRows } from "../../model-catalog/index.js";
import type { NormalizedModelCatalogRow } from "../../model-catalog/index.js";
import type { NormalizedModelCatalogRow } from "../../model-catalog/types.js";
import { loadManifestMetadataSnapshot } from "../../plugins/manifest-contract-eligibility.js";
import type { PluginManifestRegistry } from "../../plugins/manifest-registry.js";
import type { PluginMetadataSnapshot } from "../../plugins/plugin-metadata-snapshot.types.js";

View File

@@ -4,7 +4,7 @@ import {
loadOpenClawProviderIndex,
planProviderIndexModelCatalogRows,
} from "../../model-catalog/index.js";
import type { NormalizedModelCatalogRow } from "../../model-catalog/index.js";
import type { NormalizedModelCatalogRow } from "../../model-catalog/types.js";
import { normalizePluginsConfig, resolveEffectiveEnableState } from "../../plugins/config-state.js";
export function loadProviderIndexCatalogRowsForList(params: {

View File

@@ -8,7 +8,7 @@ import type { ModelDefinitionConfig, ModelProviderConfig } from "../../config/ty
import type { OpenClawConfig } from "../../config/types.openclaw.js";
import type { ModelRegistry } from "../../llm/model-registry.js";
import type { Model } from "../../llm/types.js";
import type { NormalizedModelCatalogRow } from "../../model-catalog/index.js";
import type { NormalizedModelCatalogRow } from "../../model-catalog/types.js";
import type { PluginMetadataSnapshot } from "../../plugins/plugin-metadata-snapshot.types.js";
import type { ProviderRuntimeModel } from "../../plugins/provider-runtime-model.types.js";
import { normalizeProviderResolvedModelWithPlugin } from "../../plugins/provider-runtime.js";

View File

@@ -1,5 +1,5 @@
import type { OpenClawConfig } from "../../config/types.openclaw.js";
import type { NormalizedModelCatalogRow } from "../../model-catalog/index.js";
import type { NormalizedModelCatalogRow } from "../../model-catalog/types.js";
import type { PluginMetadataSnapshot } from "../../plugins/plugin-metadata-snapshot.types.js";
import { createLazyImportLoader } from "../../shared/lazy-promise.js";

View File

@@ -11,7 +11,8 @@ import { resolvePluginWebSearchConfig } from "../config/plugin-web-search-config
import type { ModelDefinitionConfig } from "../config/types.models.js";
import type { OpenClawConfig } from "../config/types.openclaw.js";
import { createSubsystemLogger } from "../logging/subsystem.js";
import { planManifestModelCatalogRows, type ModelCatalogCost } from "../model-catalog/index.js";
import { planManifestModelCatalogRows } from "../model-catalog/index.js";
import type { ModelCatalogCost } from "../model-catalog/types.js";
import { isInstalledPluginEnabled } from "../plugins/installed-plugin-index.js";
import type { PluginManifestRegistry } from "../plugins/manifest-registry.js";
import type {

View File

@@ -1,5 +1,4 @@
export { mergeModelCatalogRowsByAuthority } from "./authority.js";
export { normalizeModelCatalog, normalizeModelCatalogRows } from "./normalize.js";
export { loadOpenClawProviderIndex } from "./provider-index/index.js";
export {
planManifestModelCatalogRows,

View File

@@ -1,10 +1,10 @@
import { normalizeModelCatalogProviderRows } from "@openclaw/model-catalog-core/model-catalog-normalize";
import {
buildModelCatalogMergeKey,
normalizeModelCatalogProviderId,
} from "@openclaw/model-catalog-core/model-catalog-refs";
import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";
import { normalizeUniqueStringEntries } from "../shared/string-normalization.js";
import { normalizeModelCatalogProviderRows } from "./normalize.js";
import type {
ModelCatalog,
ModelCatalogAlias,

View File

@@ -1,5 +1,5 @@
import { normalizeModelCatalogProviderRows } from "@openclaw/model-catalog-core/model-catalog-normalize";
import { normalizeModelCatalogProviderId } from "@openclaw/model-catalog-core/model-catalog-refs";
import { normalizeModelCatalogProviderRows } from "./normalize.js";
import type { OpenClawProviderIndex } from "./provider-index/index.js";
import type { ModelCatalogProvider, NormalizedModelCatalogRow } from "./types.js";

View File

@@ -1,3 +1,4 @@
import { normalizeModelCatalog } from "@openclaw/model-catalog-core/model-catalog-normalize";
import { normalizeModelCatalogProviderId } from "@openclaw/model-catalog-core/model-catalog-refs";
import { parseClawHubPluginSpec } from "../../infra/clawhub-spec.js";
import { parseRegistryNpmSpec } from "../../infra/npm-registry-spec.js";
@@ -6,7 +7,6 @@ import { asFiniteNumber } from "../../shared/number-coercion.js";
import { normalizeOptionalString } from "../../shared/string-coerce.js";
import { normalizeUniqueTrimmedStringList } from "../../shared/string-normalization.js";
import { isRecord } from "../../utils.js";
import { normalizeModelCatalog } from "../normalize.js";
import type { ModelCatalogProvider } from "../types.js";
import type {
OpenClawProviderIndex,

View File

@@ -4,12 +4,12 @@
// without recursing through provider-specific facades.
import { createHash } from "node:crypto";
import { normalizeModelCatalog } from "@openclaw/model-catalog-core/model-catalog-normalize";
import { findNormalizedProviderKey } from "@openclaw/model-catalog-core/provider-id";
import { normalizeConfiguredProviderCatalogModelId } from "../agents/model-ref-shared.js";
import { resolveProviderRequestCapabilities } from "../agents/provider-attribution.js";
import type { ModelDefinitionConfig } from "../config/types.models.js";
import type { OpenClawConfig } from "../config/types.openclaw.js";
import { normalizeModelCatalog } from "../model-catalog/normalize.js";
import type {
ModelCatalogCost,
ModelCatalogModel,

View File

@@ -10,6 +10,10 @@ const LEGACY_MODEL_CATALOG_BRIDGES = new Map([
path.join(REPO_ROOT, "src/model-catalog/refs.ts"),
"@openclaw/model-catalog-core/model-catalog-refs",
],
[
path.join(REPO_ROOT, "src/model-catalog/normalize.ts"),
"@openclaw/model-catalog-core/model-catalog-normalize",
],
[
path.join(REPO_ROOT, "src/config/model-refs.ts"),
"@openclaw/model-catalog-core/configured-model-refs",

View File

@@ -1,24 +1,24 @@
import fs from "node:fs";
import path from "node:path";
import { normalizeModelCatalog } from "@openclaw/model-catalog-core/model-catalog-normalize";
import { normalizeModelCatalogProviderId } from "@openclaw/model-catalog-core/model-catalog-refs";
import type { ChannelConfigRuntimeSchema } from "../channels/plugins/types.config.js";
import { MANIFEST_KEY } from "../compat/legacy-names.js";
import { ENV_SECRET_REF_ID_RE } from "../config/types.secrets.js";
import { matchRootFileOpenFailure, openRootFileSync } from "../infra/boundary-file-read.js";
import { isBlockedObjectKey } from "../infra/prototype-keys.js";
import {
normalizeModelCatalog,
type ModelCatalog,
type ModelCatalogAlias,
type ModelCatalogCost,
type ModelCatalogDiscovery,
type ModelCatalogInput,
type ModelCatalogModel,
type ModelCatalogProvider,
type ModelCatalogStatus,
type ModelCatalogSuppression,
type ModelCatalogTieredCost,
} from "../model-catalog/index.js";
import type {
ModelCatalog,
ModelCatalogAlias,
ModelCatalogCost,
ModelCatalogDiscovery,
ModelCatalogInput,
ModelCatalogModel,
ModelCatalogProvider,
ModelCatalogStatus,
ModelCatalogSuppression,
ModelCatalogTieredCost,
} from "../model-catalog/types.js";
import type { JsonSchemaObject } from "../shared/json-schema.types.js";
import { normalizeOptionalString } from "../shared/string-coerce.js";
import { normalizeTrimmedStringList } from "../shared/string-normalization.js";

View File

@@ -840,6 +840,20 @@ const WORKSPACE_PACKAGE_ALIAS_ENTRIES = [
srcFile: "model-catalog-refs.ts",
distFile: "model-catalog-refs.mjs",
},
{
packageName: "@openclaw/model-catalog-core",
packageDir: "model-catalog-core",
subpath: "model-catalog-normalize",
srcFile: "model-catalog-normalize.ts",
distFile: "model-catalog-normalize.mjs",
},
{
packageName: "@openclaw/model-catalog-core",
packageDir: "model-catalog-core",
subpath: "model-catalog-types",
srcFile: "model-catalog-types.ts",
distFile: "model-catalog-types.mjs",
},
{
packageName: "@openclaw/model-catalog-core",
packageDir: "model-catalog-core",

View File

@@ -257,6 +257,26 @@ export const sharedVitestConfig = {
"model-catalog-refs.ts",
),
},
{
find: "@openclaw/model-catalog-core/model-catalog-normalize",
replacement: path.join(
repoRoot,
"packages",
"model-catalog-core",
"src",
"model-catalog-normalize.ts",
),
},
{
find: "@openclaw/model-catalog-core/model-catalog-types",
replacement: path.join(
repoRoot,
"packages",
"model-catalog-core",
"src",
"model-catalog-types.ts",
),
},
{
find: "@openclaw/model-catalog-core/provider-id",
replacement: path.join(repoRoot, "packages", "model-catalog-core", "src", "provider-id.ts"),

View File

@@ -40,9 +40,15 @@
"@openclaw/model-catalog-core/configured-model-refs": [
"./packages/model-catalog-core/src/configured-model-refs.ts"
],
"@openclaw/model-catalog-core/model-catalog-normalize": [
"./packages/model-catalog-core/src/model-catalog-normalize.ts"
],
"@openclaw/model-catalog-core/model-catalog-refs": [
"./packages/model-catalog-core/src/model-catalog-refs.ts"
],
"@openclaw/model-catalog-core/model-catalog-types": [
"./packages/model-catalog-core/src/model-catalog-types.ts"
],
"@openclaw/model-catalog-core/provider-id": [
"./packages/model-catalog-core/src/provider-id.ts"
],

View File

@@ -470,7 +470,9 @@ function buildModelCatalogCoreDistEntries(): Record<string, string> {
return {
index: "packages/model-catalog-core/src/index.ts",
"configured-model-refs": "packages/model-catalog-core/src/configured-model-refs.ts",
"model-catalog-normalize": "packages/model-catalog-core/src/model-catalog-normalize.ts",
"model-catalog-refs": "packages/model-catalog-core/src/model-catalog-refs.ts",
"model-catalog-types": "packages/model-catalog-core/src/model-catalog-types.ts",
"provider-id": "packages/model-catalog-core/src/provider-id.ts",
"provider-model-id-normalization":
"packages/model-catalog-core/src/provider-model-id-normalization.ts",