























@@ -7,6 +7,12 @@ import { resolveProviderRequestCapabilities } from "../agents/provider-attributi
77import { findNormalizedProviderKey } from "../agents/provider-id.js";
88import type { ModelDefinitionConfig } from "../config/types.models.js";
99import type { OpenClawConfig } from "../config/types.openclaw.js";
10+import type {
11+ModelCatalogCost,
12+ModelCatalogModel,
13+ModelCatalogProvider,
14+ModelCatalogTieredCost,
15+} from "../model-catalog/types.js";
1016import type { ModelProviderConfig } from "./provider-model-shared.js";
11171218export type { ProviderCatalogContext, ProviderCatalogResult } from "../plugins/types.js";
@@ -26,6 +32,69 @@ export type ConfiguredProviderCatalogEntry = {
2632input?: Array<"text" | "image" | "audio" | "video" | "document">;
2733};
283435+function cloneManifestCatalogTieredCost(
36+tier: ModelCatalogTieredCost,
37+): NonNullable<ModelDefinitionConfig["cost"]["tieredPricing"]>[number] {
38+return {
39+input: tier.input,
40+output: tier.output,
41+cacheRead: tier.cacheRead,
42+cacheWrite: tier.cacheWrite,
43+range: tier.range.length === 1 ? [tier.range[0]] : [tier.range[0], tier.range[1]],
44+};
45+}
46+47+function cloneManifestCatalogCost(cost: ModelCatalogCost): ModelDefinitionConfig["cost"] {
48+return {
49+input: cost.input ?? 0,
50+output: cost.output ?? 0,
51+cacheRead: cost.cacheRead ?? 0,
52+cacheWrite: cost.cacheWrite ?? 0,
53+ ...(cost.tieredPricing
54+ ? { tieredPricing: cost.tieredPricing.map(cloneManifestCatalogTieredCost) }
55+ : {}),
56+};
57+}
58+59+function buildManifestCatalogModel(model: ModelCatalogModel): ModelDefinitionConfig {
60+if (model.contextWindow === undefined) {
61+throw new Error(`Manifest modelCatalog row ${model.id} is missing contextWindow`);
62+}
63+if (model.maxTokens === undefined) {
64+throw new Error(`Manifest modelCatalog row ${model.id} is missing maxTokens`);
65+}
66+const input = model.input?.filter((item) => item !== "document") ?? ["text"];
67+return {
68+id: model.id,
69+name: model.name ?? model.id,
70+ ...(model.api ? { api: model.api } : {}),
71+ ...(model.baseUrl ? { baseUrl: model.baseUrl } : {}),
72+reasoning: model.reasoning ?? false,
73+input: input.length > 0 ? input : ["text"],
74+cost: cloneManifestCatalogCost(model.cost ?? {}),
75+contextWindow: model.contextWindow,
76+ ...(model.contextTokens !== undefined ? { contextTokens: model.contextTokens } : {}),
77+maxTokens: model.maxTokens,
78+ ...(model.headers ? { headers: { ...model.headers } } : {}),
79+ ...(model.compat ? { compat: { ...model.compat } } : {}),
80+};
81+}
82+83+export function buildManifestModelProviderConfig(params: {
84+providerId: string;
85+catalog: ModelCatalogProvider | undefined;
86+}): ModelProviderConfig {
87+if (!params.catalog) {
88+throw new Error(`Missing modelCatalog.providers.${params.providerId}`);
89+}
90+return {
91+baseUrl: params.catalog.baseUrl ?? "",
92+ ...(params.catalog.api ? { api: params.catalog.api } : {}),
93+ ...(params.catalog.headers ? { headers: { ...params.catalog.headers } } : {}),
94+models: params.catalog.models.map(buildManifestCatalogModel),
95+};
96+}
97+2998function normalizeConfiguredCatalogModelInput(
3099input: unknown,
31100): ConfiguredProviderCatalogEntry["input"] | undefined {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。