mirror of https://github.com/openclaw/openclaw.git
refactor: split models-config source-managed helpers
This commit is contained in:
parent
7db79b04c6
commit
5c52824d3e
|
|
@ -0,0 +1,153 @@
|
|||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { resolveSecretInputRef } from "../config/types.secrets.js";
|
||||
import { isRecord } from "../utils.js";
|
||||
import {
|
||||
resolveNonEnvSecretRefApiKeyMarker,
|
||||
resolveNonEnvSecretRefHeaderValueMarker,
|
||||
resolveEnvSecretRefHeaderValueMarker,
|
||||
} from "./model-auth-markers.js";
|
||||
import type { ProviderConfig, SecretDefaults } from "./models-config.providers.secrets.js";
|
||||
|
||||
type ModelsConfig = NonNullable<OpenClawConfig["models"]>;
|
||||
|
||||
function normalizeSourceProviderLookup(
|
||||
providers: ModelsConfig["providers"] | undefined,
|
||||
): Record<string, ProviderConfig> {
|
||||
if (!providers) {
|
||||
return {};
|
||||
}
|
||||
const out: Record<string, ProviderConfig> = {};
|
||||
for (const [key, provider] of Object.entries(providers)) {
|
||||
const normalizedKey = key.trim();
|
||||
if (!normalizedKey || !isRecord(provider)) {
|
||||
continue;
|
||||
}
|
||||
out[normalizedKey] = provider;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function resolveSourceManagedApiKeyMarker(params: {
|
||||
sourceProvider: ProviderConfig | undefined;
|
||||
sourceSecretDefaults: SecretDefaults | undefined;
|
||||
}): string | undefined {
|
||||
const sourceApiKeyRef = resolveSecretInputRef({
|
||||
value: params.sourceProvider?.apiKey,
|
||||
defaults: params.sourceSecretDefaults,
|
||||
}).ref;
|
||||
if (!sourceApiKeyRef || !sourceApiKeyRef.id.trim()) {
|
||||
return undefined;
|
||||
}
|
||||
return sourceApiKeyRef.source === "env"
|
||||
? sourceApiKeyRef.id.trim()
|
||||
: resolveNonEnvSecretRefApiKeyMarker(sourceApiKeyRef.source);
|
||||
}
|
||||
|
||||
function resolveSourceManagedHeaderMarkers(params: {
|
||||
sourceProvider: ProviderConfig | undefined;
|
||||
sourceSecretDefaults: SecretDefaults | undefined;
|
||||
}): Record<string, string> {
|
||||
const sourceHeaders = isRecord(params.sourceProvider?.headers)
|
||||
? (params.sourceProvider.headers as Record<string, unknown>)
|
||||
: undefined;
|
||||
if (!sourceHeaders) {
|
||||
return {};
|
||||
}
|
||||
const markers: Record<string, string> = {};
|
||||
for (const [headerName, headerValue] of Object.entries(sourceHeaders)) {
|
||||
const sourceHeaderRef = resolveSecretInputRef({
|
||||
value: headerValue,
|
||||
defaults: params.sourceSecretDefaults,
|
||||
}).ref;
|
||||
if (!sourceHeaderRef || !sourceHeaderRef.id.trim()) {
|
||||
continue;
|
||||
}
|
||||
markers[headerName] =
|
||||
sourceHeaderRef.source === "env"
|
||||
? resolveEnvSecretRefHeaderValueMarker(sourceHeaderRef.id)
|
||||
: resolveNonEnvSecretRefHeaderValueMarker(sourceHeaderRef.source);
|
||||
}
|
||||
return markers;
|
||||
}
|
||||
|
||||
export function enforceSourceManagedProviderSecrets(params: {
|
||||
providers: ModelsConfig["providers"];
|
||||
sourceProviders: ModelsConfig["providers"] | undefined;
|
||||
sourceSecretDefaults?: SecretDefaults;
|
||||
secretRefManagedProviders?: Set<string>;
|
||||
}): ModelsConfig["providers"] {
|
||||
const { providers } = params;
|
||||
if (!providers) {
|
||||
return providers;
|
||||
}
|
||||
const sourceProvidersByKey = normalizeSourceProviderLookup(params.sourceProviders);
|
||||
if (Object.keys(sourceProvidersByKey).length === 0) {
|
||||
return providers;
|
||||
}
|
||||
|
||||
let nextProviders: Record<string, ProviderConfig> | null = null;
|
||||
for (const [providerKey, provider] of Object.entries(providers)) {
|
||||
if (!isRecord(provider)) {
|
||||
continue;
|
||||
}
|
||||
const sourceProvider = sourceProvidersByKey[providerKey.trim()];
|
||||
if (!sourceProvider) {
|
||||
continue;
|
||||
}
|
||||
let nextProvider = provider;
|
||||
let providerMutated = false;
|
||||
|
||||
const sourceApiKeyMarker = resolveSourceManagedApiKeyMarker({
|
||||
sourceProvider,
|
||||
sourceSecretDefaults: params.sourceSecretDefaults,
|
||||
});
|
||||
if (sourceApiKeyMarker) {
|
||||
params.secretRefManagedProviders?.add(providerKey.trim());
|
||||
if (nextProvider.apiKey !== sourceApiKeyMarker) {
|
||||
providerMutated = true;
|
||||
nextProvider = {
|
||||
...nextProvider,
|
||||
apiKey: sourceApiKeyMarker,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const sourceHeaderMarkers = resolveSourceManagedHeaderMarkers({
|
||||
sourceProvider,
|
||||
sourceSecretDefaults: params.sourceSecretDefaults,
|
||||
});
|
||||
if (Object.keys(sourceHeaderMarkers).length > 0) {
|
||||
const currentHeaders = isRecord(nextProvider.headers)
|
||||
? (nextProvider.headers as Record<string, unknown>)
|
||||
: undefined;
|
||||
const nextHeaders = {
|
||||
...(currentHeaders as Record<string, NonNullable<ProviderConfig["headers"]>[string]>),
|
||||
};
|
||||
let headersMutated = !currentHeaders;
|
||||
for (const [headerName, marker] of Object.entries(sourceHeaderMarkers)) {
|
||||
if (nextHeaders[headerName] === marker) {
|
||||
continue;
|
||||
}
|
||||
headersMutated = true;
|
||||
nextHeaders[headerName] = marker;
|
||||
}
|
||||
if (headersMutated) {
|
||||
providerMutated = true;
|
||||
nextProvider = {
|
||||
...nextProvider,
|
||||
headers: nextHeaders,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (!providerMutated) {
|
||||
continue;
|
||||
}
|
||||
if (!nextProviders) {
|
||||
nextProviders = { ...providers };
|
||||
}
|
||||
nextProviders[providerKey] = nextProvider;
|
||||
}
|
||||
|
||||
return nextProviders ?? providers;
|
||||
}
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { resolveSecretInputRef } from "../config/types.secrets.js";
|
||||
import { resolveBedrockConfigApiKey } from "../plugin-sdk/amazon-bedrock.js";
|
||||
import { resolveAnthropicVertexConfigApiKey } from "../plugin-sdk/anthropic-vertex.js";
|
||||
import {
|
||||
|
|
@ -8,14 +7,8 @@ import {
|
|||
} from "../plugin-sdk/google.js";
|
||||
import { applyModelStudioNativeStreamingUsageCompat } from "../plugin-sdk/modelstudio.js";
|
||||
import { applyMoonshotNativeStreamingUsageCompat } from "../plugin-sdk/moonshot.js";
|
||||
import { isRecord } from "../utils.js";
|
||||
import { ensureAuthProfileStore } from "./auth-profiles.js";
|
||||
export * from "./models-config.providers.static.js";
|
||||
import {
|
||||
resolveNonEnvSecretRefApiKeyMarker,
|
||||
resolveNonEnvSecretRefHeaderValueMarker,
|
||||
resolveEnvSecretRefHeaderValueMarker,
|
||||
} from "./model-auth-markers.js";
|
||||
export { resolveImplicitProviders } from "./models-config.providers.implicit.js";
|
||||
import type { ProviderConfig, SecretDefaults } from "./models-config.providers.secrets.js";
|
||||
import {
|
||||
|
|
@ -25,6 +18,7 @@ import {
|
|||
resolveApiKeyFromProfiles,
|
||||
resolveMissingProviderApiKey,
|
||||
} from "./models-config.providers.secrets.js";
|
||||
import { enforceSourceManagedProviderSecrets } from "./models-config.providers.source-managed.js";
|
||||
export type {
|
||||
ProfileApiKeyResolution,
|
||||
ProviderApiKeyResolver,
|
||||
|
|
@ -32,6 +26,7 @@ export type {
|
|||
ProviderConfig,
|
||||
SecretDefaults,
|
||||
} from "./models-config.providers.secrets.js";
|
||||
export { enforceSourceManagedProviderSecrets };
|
||||
export { resolveOllamaApiBase } from "../plugin-sdk/ollama-surface.js";
|
||||
export { normalizeGoogleModelId } from "../plugin-sdk/google.js";
|
||||
export { normalizeXaiModelId } from "../plugin-sdk/xai.js";
|
||||
|
|
@ -76,148 +71,6 @@ function normalizeProviderSpecificConfig(
|
|||
return provider;
|
||||
}
|
||||
|
||||
function normalizeSourceProviderLookup(
|
||||
providers: ModelsConfig["providers"] | undefined,
|
||||
): Record<string, ProviderConfig> {
|
||||
if (!providers) {
|
||||
return {};
|
||||
}
|
||||
const out: Record<string, ProviderConfig> = {};
|
||||
for (const [key, provider] of Object.entries(providers)) {
|
||||
const normalizedKey = key.trim();
|
||||
if (!normalizedKey || !isRecord(provider)) {
|
||||
continue;
|
||||
}
|
||||
out[normalizedKey] = provider;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function resolveSourceManagedApiKeyMarker(params: {
|
||||
sourceProvider: ProviderConfig | undefined;
|
||||
sourceSecretDefaults: SecretDefaults | undefined;
|
||||
}): string | undefined {
|
||||
const sourceApiKeyRef = resolveSecretInputRef({
|
||||
value: params.sourceProvider?.apiKey,
|
||||
defaults: params.sourceSecretDefaults,
|
||||
}).ref;
|
||||
if (!sourceApiKeyRef || !sourceApiKeyRef.id.trim()) {
|
||||
return undefined;
|
||||
}
|
||||
return sourceApiKeyRef.source === "env"
|
||||
? sourceApiKeyRef.id.trim()
|
||||
: resolveNonEnvSecretRefApiKeyMarker(sourceApiKeyRef.source);
|
||||
}
|
||||
|
||||
function resolveSourceManagedHeaderMarkers(params: {
|
||||
sourceProvider: ProviderConfig | undefined;
|
||||
sourceSecretDefaults: SecretDefaults | undefined;
|
||||
}): Record<string, string> {
|
||||
const sourceHeaders = isRecord(params.sourceProvider?.headers)
|
||||
? (params.sourceProvider.headers as Record<string, unknown>)
|
||||
: undefined;
|
||||
if (!sourceHeaders) {
|
||||
return {};
|
||||
}
|
||||
const markers: Record<string, string> = {};
|
||||
for (const [headerName, headerValue] of Object.entries(sourceHeaders)) {
|
||||
const sourceHeaderRef = resolveSecretInputRef({
|
||||
value: headerValue,
|
||||
defaults: params.sourceSecretDefaults,
|
||||
}).ref;
|
||||
if (!sourceHeaderRef || !sourceHeaderRef.id.trim()) {
|
||||
continue;
|
||||
}
|
||||
markers[headerName] =
|
||||
sourceHeaderRef.source === "env"
|
||||
? resolveEnvSecretRefHeaderValueMarker(sourceHeaderRef.id)
|
||||
: resolveNonEnvSecretRefHeaderValueMarker(sourceHeaderRef.source);
|
||||
}
|
||||
return markers;
|
||||
}
|
||||
|
||||
export function enforceSourceManagedProviderSecrets(params: {
|
||||
providers: ModelsConfig["providers"];
|
||||
sourceProviders: ModelsConfig["providers"] | undefined;
|
||||
sourceSecretDefaults?: SecretDefaults;
|
||||
secretRefManagedProviders?: Set<string>;
|
||||
}): ModelsConfig["providers"] {
|
||||
const { providers } = params;
|
||||
if (!providers) {
|
||||
return providers;
|
||||
}
|
||||
const sourceProvidersByKey = normalizeSourceProviderLookup(params.sourceProviders);
|
||||
if (Object.keys(sourceProvidersByKey).length === 0) {
|
||||
return providers;
|
||||
}
|
||||
|
||||
let nextProviders: Record<string, ProviderConfig> | null = null;
|
||||
for (const [providerKey, provider] of Object.entries(providers)) {
|
||||
if (!isRecord(provider)) {
|
||||
continue;
|
||||
}
|
||||
const sourceProvider = sourceProvidersByKey[providerKey.trim()];
|
||||
if (!sourceProvider) {
|
||||
continue;
|
||||
}
|
||||
let nextProvider = provider;
|
||||
let providerMutated = false;
|
||||
|
||||
const sourceApiKeyMarker = resolveSourceManagedApiKeyMarker({
|
||||
sourceProvider,
|
||||
sourceSecretDefaults: params.sourceSecretDefaults,
|
||||
});
|
||||
if (sourceApiKeyMarker) {
|
||||
params.secretRefManagedProviders?.add(providerKey.trim());
|
||||
if (nextProvider.apiKey !== sourceApiKeyMarker) {
|
||||
providerMutated = true;
|
||||
nextProvider = {
|
||||
...nextProvider,
|
||||
apiKey: sourceApiKeyMarker,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const sourceHeaderMarkers = resolveSourceManagedHeaderMarkers({
|
||||
sourceProvider,
|
||||
sourceSecretDefaults: params.sourceSecretDefaults,
|
||||
});
|
||||
if (Object.keys(sourceHeaderMarkers).length > 0) {
|
||||
const currentHeaders = isRecord(nextProvider.headers)
|
||||
? (nextProvider.headers as Record<string, unknown>)
|
||||
: undefined;
|
||||
const nextHeaders = {
|
||||
...(currentHeaders as Record<string, NonNullable<ProviderConfig["headers"]>[string]>),
|
||||
};
|
||||
let headersMutated = !currentHeaders;
|
||||
for (const [headerName, marker] of Object.entries(sourceHeaderMarkers)) {
|
||||
if (nextHeaders[headerName] === marker) {
|
||||
continue;
|
||||
}
|
||||
headersMutated = true;
|
||||
nextHeaders[headerName] = marker;
|
||||
}
|
||||
if (headersMutated) {
|
||||
providerMutated = true;
|
||||
nextProvider = {
|
||||
...nextProvider,
|
||||
headers: nextHeaders,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (!providerMutated) {
|
||||
continue;
|
||||
}
|
||||
if (!nextProviders) {
|
||||
nextProviders = { ...providers };
|
||||
}
|
||||
nextProviders[providerKey] = nextProvider;
|
||||
}
|
||||
|
||||
return nextProviders ?? providers;
|
||||
}
|
||||
|
||||
export function normalizeProviders(params: {
|
||||
providers: ModelsConfig["providers"];
|
||||
agentDir: string;
|
||||
|
|
|
|||
Loading…
Reference in New Issue