




























@@ -2,44 +2,66 @@ import {
22buildModelCatalogMergeKey,
33buildModelCatalogRef,
44normalizeModelCatalogProviderId,
5-} from "@openclaw/model-catalog-core/model-catalog-refs";
5+} from "./model-catalog-refs.js";
66import {
7-MODEL_APIS,
8-isModelThinkingFormat,
9-type ModelApi,
10-type ModelCompatConfig,
11-type ModelImageInputConfig,
12-type ModelMediaInputConfig,
13-} from "../config/types.models.js";
14-import { isBlockedObjectKey } from "../infra/prototype-keys.js";
15-import { normalizeOptionalString } from "../shared/string-coerce.js";
16-import {
17-normalizeOptionalTrimmedStringList,
18-normalizeTrimmedStringList,
19-} from "../shared/string-normalization.js";
20-import { isRecord } from "../utils.js";
21-import type {
22-ModelCatalog,
23-ModelCatalogAlias,
24-ModelCatalogCost,
25-ModelCatalogDiscovery,
26-ModelCatalogInput,
27-ModelCatalogModel,
28-ModelCatalogProvider,
29-ModelCatalogSource,
30-ModelCatalogStatus,
31-ModelCatalogSuppression,
32-ModelCatalogTieredCost,
33-NormalizedModelCatalogRow,
34-} from "./types.js";
7+MODEL_CATALOG_APIS,
8+isModelCatalogThinkingFormat,
9+type ModelCatalog,
10+type ModelCatalogAlias,
11+type ModelCatalogApi,
12+type ModelCatalogCompatConfig,
13+type ModelCatalogCost,
14+type ModelCatalogDiscovery,
15+type ModelCatalogImageInputConfig,
16+type ModelCatalogInput,
17+type ModelCatalogMediaInputConfig,
18+type ModelCatalogModel,
19+type ModelCatalogProvider,
20+type ModelCatalogSource,
21+type ModelCatalogStatus,
22+type ModelCatalogSuppression,
23+type ModelCatalogTieredCost,
24+type NormalizedModelCatalogRow,
25+} from "./model-catalog-types.js";
35263627const MODEL_CATALOG_INPUTS = new Set(["text", "image", "document"]);
3728const MODEL_CATALOG_DISCOVERY_MODES = new Set(["static", "refreshable", "runtime"]);
3829const MODEL_CATALOG_STATUSES = new Set(["available", "preview", "deprecated", "disabled"]);
39-const MODEL_CATALOG_APIS = new Set<string>(MODEL_APIS);
30+const MODEL_CATALOG_API_SET = new Set<string>(MODEL_CATALOG_APIS);
4031const DEFAULT_MODEL_INPUT: ModelCatalogInput[] = ["text"];
4132const DEFAULT_MODEL_STATUS: ModelCatalogStatus = "available";
423334+function isRecord(value: unknown): value is Record<string, unknown> {
35+return typeof value === "object" && value !== null && !Array.isArray(value);
36+}
37+38+function isBlockedObjectKey(key: string): boolean {
39+return key === "__proto__" || key === "prototype" || key === "constructor";
40+}
41+42+function normalizeOptionalString(value: unknown): string | undefined {
43+if (typeof value !== "string") {
44+return undefined;
45+}
46+const trimmed = value.trim();
47+return trimmed ? trimmed : undefined;
48+}
49+50+function normalizeTrimmedStringList(value: unknown): string[] {
51+if (!Array.isArray(value)) {
52+return [];
53+}
54+return value.flatMap((entry) => {
55+const normalized = normalizeOptionalString(entry);
56+return normalized ? [normalized] : [];
57+});
58+}
59+60+function normalizeOptionalTrimmedStringList(value: unknown): string[] | undefined {
61+const normalized = normalizeTrimmedStringList(value);
62+return normalized.length > 0 ? normalized : undefined;
63+}
64+4365function normalizeSafeRecordKey(value: unknown): string {
4466const key = normalizeOptionalString(value) ?? "";
4567return key && !isBlockedObjectKey(key) ? key : "";
@@ -81,9 +103,9 @@ function mergeStringMaps(
81103return { ...base, ...override };
82104}
8310584-function normalizeModelCatalogApi(value: unknown): ModelApi | undefined {
106+function normalizeModelCatalogApi(value: unknown): ModelCatalogApi | undefined {
85107const api = normalizeOptionalString(value) ?? "";
86-return MODEL_CATALOG_APIS.has(api) ? (api as ModelApi) : undefined;
108+return MODEL_CATALOG_API_SET.has(api) ? (api as ModelCatalogApi) : undefined;
87109}
8811089111function normalizeModelCatalogInputs(value: unknown): ModelCatalogInput[] | undefined {
@@ -165,7 +187,7 @@ function normalizeModelCatalogCost(value: unknown): ModelCatalogCost | undefined
165187return Object.keys(cost).length > 0 ? cost : undefined;
166188}
167189168-function normalizeModelCatalogCompat(value: unknown): ModelCompatConfig | undefined {
190+function normalizeModelCatalogCompat(value: unknown): ModelCatalogCompatConfig | undefined {
169191if (!isRecord(value)) {
170192return undefined;
171193}
@@ -230,27 +252,29 @@ function normalizeModelCatalogCompat(value: unknown): ModelCompatConfig | undefi
230252}
231253232254const thinkingFormat = normalizeOptionalString(value.thinkingFormat) ?? "";
233-if (isModelThinkingFormat(thinkingFormat)) {
255+if (isModelCatalogThinkingFormat(thinkingFormat)) {
234256compat.thinkingFormat = thinkingFormat;
235257}
236258237-return Object.keys(compat).length > 0 ? (compat as ModelCompatConfig) : undefined;
259+return Object.keys(compat).length > 0 ? (compat as ModelCatalogCompatConfig) : undefined;
238260}
239261240262function normalizeModelCatalogStatus(value: unknown): ModelCatalogStatus | undefined {
241263const status = normalizeOptionalString(value) ?? "";
242264return MODEL_CATALOG_STATUSES.has(status) ? (status as ModelCatalogStatus) : undefined;
243265}
244266245-function normalizeModelCatalogImageTokenMode(value: unknown): ModelImageInputConfig["tokenMode"] {
267+function normalizeModelCatalogImageTokenMode(
268+value: unknown,
269+): ModelCatalogImageInputConfig["tokenMode"] {
246270const tokenMode = normalizeOptionalString(value) ?? "";
247271if (tokenMode === "tile" || tokenMode === "detail" || tokenMode === "provider") {
248272return tokenMode;
249273}
250274return undefined;
251275}
252276253-function normalizeModelCatalogMediaInput(value: unknown): ModelMediaInputConfig | undefined {
277+function normalizeModelCatalogMediaInput(value: unknown): ModelCatalogMediaInputConfig | undefined {
254278if (!isRecord(value) || !isRecord(value.image)) {
255279return undefined;
256280}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。