Files
openclaw/src/agents/model-ref-shared.ts
Peter Steinberger 8eeaa45729 refactor: route model catalog imports to core package
Route internal model catalog imports to the extracted @openclaw/model-catalog-core package and delete obsolete internal facades.

Keep public SDK declarations self-contained by wrapping core helpers at public boundaries instead of leaking private package imports.

Verification:
- pnpm test src/plugins/contracts/model-catalog-core-imports.test.ts src/plugins/sdk-alias.test.ts packages/model-catalog-core/src/configured-model-refs.test.ts packages/model-catalog-core/src/provider-model-id-normalize.test.ts packages/model-catalog-core/src/provider-model-id-normalization.test.ts src/config/config.model-ref-validation.test.ts src/agents/model-selection.test.ts src/plugin-sdk/provider-model-shared.test.ts -- --reporter=verbose
- pnpm check:test-types
- pnpm test:extensions:package-boundary:compile
- pnpm build
- rg "@openclaw/model-catalog-core" dist/plugin-sdk packages/plugin-sdk/dist -n --glob '*.d.ts' || true
- git diff --check
- autoreview clean after fix

CI note: merged with admin override because checks-node-agentic-commands-doctor and checks-node-core-runtime-infra-state failed twice with exit 143/no-output watchdog termination after prior passing test output, while relevant local proof and the rest of CI were green.
2026-05-30 17:48:18 +01:00

143 lines
4.4 KiB
TypeScript

import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id";
import {
collectManifestModelIdNormalizationPolicies,
normalizeBuiltInProviderModelId,
normalizeConfiguredProviderCatalogModelRef,
normalizeConfiguredProviderCatalogModelId as normalizeConfiguredProviderCatalogModelIdShared,
normalizeStaticProviderModelIdWithPolicies,
} from "@openclaw/model-catalog-core/provider-model-id-normalization";
import { normalizeProviderModelIdWithManifest } from "../plugins/manifest-model-id-normalization.js";
import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";
type StaticModelRef = {
provider: string;
model: string;
};
export type ProviderModelIdNormalizationOptions = {
allowManifestNormalization?: boolean;
manifestPlugins?: readonly ManifestModelIdNormalizationRecord[];
};
export type ManifestModelIdNormalizationProvider = {
aliases?: Record<string, string>;
stripPrefixes?: string[];
prefixWhenBare?: string;
prefixWhenBareAfterAliasStartsWith?: {
modelPrefix: string;
prefix: string;
}[];
};
export type ManifestModelIdNormalizationRecord = {
modelIdNormalization?: {
providers?: Record<string, ManifestModelIdNormalizationProvider>;
};
};
export function modelKey(provider: string, model: string): string {
const providerId = provider.trim();
const modelId = model.trim();
if (!providerId) {
return modelId;
}
if (!modelId) {
return providerId;
}
return normalizeLowercaseStringOrEmpty(modelId).startsWith(
`${normalizeLowercaseStringOrEmpty(providerId)}/`,
)
? modelId
: `${providerId}/${modelId}`;
}
export function normalizeStaticProviderModelId(
provider: string,
model: string,
options: ProviderModelIdNormalizationOptions = {},
): string {
const normalizedProvider = normalizeProviderId(provider);
if (options.allowManifestNormalization === false) {
return normalizeBuiltInProviderModelId(normalizedProvider, model);
}
if (options.manifestPlugins) {
return normalizeStaticProviderModelIdWithPolicies(
normalizedProvider,
model,
collectManifestModelIdNormalizationPolicies(options.manifestPlugins),
);
}
const manifestModelId =
normalizeProviderModelIdWithManifest({
provider: normalizedProvider,
context: {
provider: normalizedProvider,
modelId: model,
},
}) ?? model;
return normalizeBuiltInProviderModelId(normalizedProvider, manifestModelId);
}
export function normalizeConfiguredProviderCatalogModelId(
provider: string,
model: string,
options: ProviderModelIdNormalizationOptions = {},
): string {
if (options.allowManifestNormalization === false) {
return normalizeConfiguredProviderCatalogModelIdShared(provider, model, new Map());
}
if (options.manifestPlugins) {
return normalizeConfiguredProviderCatalogModelIdShared(
provider,
model,
collectManifestModelIdNormalizationPolicies(options.manifestPlugins),
);
}
return normalizeConfiguredProviderCatalogModelRef(
normalizeStaticProviderModelId(provider, model, options),
);
}
function parseStaticModelRef(raw: string, defaultProvider: string): StaticModelRef | null {
const trimmed = raw.trim();
if (!trimmed) {
return null;
}
const slash = trimmed.indexOf("/");
const providerRaw = slash === -1 ? defaultProvider : trimmed.slice(0, slash).trim();
const modelRaw = slash === -1 ? trimmed : trimmed.slice(slash + 1).trim();
if (!providerRaw || !modelRaw) {
return null;
}
const provider = normalizeProviderId(providerRaw);
return {
provider,
model: normalizeStaticProviderModelId(provider, modelRaw),
};
}
export function resolveStaticAllowlistModelKey(
raw: string,
defaultProvider: string,
): string | null {
const parsed = parseStaticModelRef(raw, defaultProvider);
if (!parsed) {
return null;
}
return modelKey(parsed.provider, parsed.model);
}
export function formatLiteralProviderPrefixedModelRef(provider: string, modelRef: string): string {
const providerId = normalizeProviderId(provider);
const trimmedRef = modelRef.trim();
if (!providerId || !trimmedRef) {
return trimmedRef;
}
const normalizedRef = normalizeLowercaseStringOrEmpty(trimmedRef);
const literalPrefix = `${providerId}/${providerId}/`;
if (normalizedRef.startsWith(literalPrefix)) {
return trimmedRef;
}
return normalizedRef.startsWith(`${providerId}/`) ? `${providerId}/${trimmedRef}` : trimmedRef;
}