mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 07:00:43 +00:00
fix: include local model list auth markers
This commit is contained in:
@@ -274,6 +274,36 @@ function isManagedSecretRefApiKeyMarker(apiKey: string | undefined): boolean {
|
||||
return apiKey?.trim() === NON_ENV_SECRETREF_MARKER;
|
||||
}
|
||||
|
||||
export function hasSyntheticLocalProviderAuthConfig(params: {
|
||||
cfg: OpenClawConfig | undefined;
|
||||
provider: string;
|
||||
}): boolean {
|
||||
const providerConfig = resolveProviderConfig(params.cfg, params.provider);
|
||||
if (!providerConfig) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const hasApiConfig =
|
||||
Boolean(providerConfig.api?.trim()) ||
|
||||
Boolean(providerConfig.baseUrl?.trim()) ||
|
||||
(Array.isArray(providerConfig.models) && providerConfig.models.length > 0);
|
||||
if (!hasApiConfig) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const authOverride = resolveProviderAuthOverride(params.cfg, params.provider);
|
||||
if (authOverride && authOverride !== "api-key") {
|
||||
return false;
|
||||
}
|
||||
if (!isCustomLocalProviderConfig(providerConfig)) {
|
||||
return false;
|
||||
}
|
||||
if (hasExplicitProviderApiKeyConfig(providerConfig)) {
|
||||
return false;
|
||||
}
|
||||
return Boolean(providerConfig.baseUrl && isLocalBaseUrl(providerConfig.baseUrl));
|
||||
}
|
||||
|
||||
type SyntheticProviderAuthResolution = {
|
||||
auth?: ResolvedProviderAuth;
|
||||
blockedOnManagedSecretRef?: boolean;
|
||||
@@ -340,29 +370,10 @@ function resolveSyntheticLocalProviderAuth(params: {
|
||||
return null;
|
||||
}
|
||||
|
||||
const hasApiConfig =
|
||||
Boolean(providerConfig.api?.trim()) ||
|
||||
Boolean(providerConfig.baseUrl?.trim()) ||
|
||||
(Array.isArray(providerConfig.models) && providerConfig.models.length > 0);
|
||||
if (!hasApiConfig) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const authOverride = resolveProviderAuthOverride(params.cfg, params.provider);
|
||||
if (authOverride && authOverride !== "api-key") {
|
||||
return null;
|
||||
}
|
||||
if (!isCustomLocalProviderConfig(providerConfig)) {
|
||||
return null;
|
||||
}
|
||||
if (hasExplicitProviderApiKeyConfig(providerConfig)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Custom providers pointing at a local server (e.g. llama.cpp, vLLM, LocalAI)
|
||||
// typically don't require auth. Synthesize a local key so the auth resolver
|
||||
// doesn't reject them when the user left the API key blank during setup.
|
||||
if (providerConfig.baseUrl && isLocalBaseUrl(providerConfig.baseUrl)) {
|
||||
if (hasSyntheticLocalProviderAuthConfig(params)) {
|
||||
return {
|
||||
apiKey: CUSTOM_LOCAL_AUTH_MARKER,
|
||||
source: `models.providers.${params.provider} (synthetic local key)`,
|
||||
|
||||
@@ -16,6 +16,7 @@ const listProfilesForProvider = vi.fn().mockReturnValue([]);
|
||||
const resolveEnvApiKey = vi.fn().mockReturnValue(undefined);
|
||||
const resolveAwsSdkEnvVarName = vi.fn().mockReturnValue(undefined);
|
||||
const hasUsableCustomProviderApiKey = vi.fn().mockReturnValue(false);
|
||||
const hasSyntheticLocalProviderAuthConfig = vi.fn().mockReturnValue(false);
|
||||
const loadModelCatalog = vi.fn(async () => []);
|
||||
const loadProviderCatalogModelsForList = vi.fn<() => Promise<Array<Record<string, unknown>>>>(
|
||||
async () => [],
|
||||
@@ -64,6 +65,7 @@ vi.mock("../agents/auth-profiles/store.js", () => ({
|
||||
|
||||
vi.mock("../agents/model-auth.js", () => ({
|
||||
hasUsableCustomProviderApiKey,
|
||||
hasSyntheticLocalProviderAuthConfig,
|
||||
resolveAwsSdkEnvVarName,
|
||||
resolveEnvApiKey,
|
||||
}));
|
||||
|
||||
@@ -66,6 +66,26 @@ describe("createModelListAuthIndex", () => {
|
||||
expect(index.hasProviderAuth("custom-openai")).toBe(true);
|
||||
});
|
||||
|
||||
it("records configured local custom provider markers", () => {
|
||||
const index = createModelListAuthIndex({
|
||||
cfg: {
|
||||
models: {
|
||||
providers: {
|
||||
"local-openai": {
|
||||
api: "openai-completions",
|
||||
baseUrl: "http://127.0.0.1:8080/v1",
|
||||
models: [{ id: "local-model" }],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
authStore: emptyStore,
|
||||
env: {},
|
||||
});
|
||||
|
||||
expect(index.hasProviderAuth("local-openai")).toBe(true);
|
||||
});
|
||||
|
||||
it("uses injected synthetic auth refs without loading provider runtime", () => {
|
||||
const index = createModelListAuthIndex({
|
||||
cfg: {},
|
||||
|
||||
@@ -2,7 +2,10 @@ import type { AuthProfileStore } from "../../agents/auth-profiles/types.js";
|
||||
import { resolveProviderEnvApiKeyCandidates } from "../../agents/model-auth-env-vars.js";
|
||||
import { resolveEnvApiKey } from "../../agents/model-auth-env.js";
|
||||
import { resolveAwsSdkEnvVarName } from "../../agents/model-auth-runtime-shared.js";
|
||||
import { hasUsableCustomProviderApiKey } from "../../agents/model-auth.js";
|
||||
import {
|
||||
hasSyntheticLocalProviderAuthConfig,
|
||||
hasUsableCustomProviderApiKey,
|
||||
} from "../../agents/model-auth.js";
|
||||
import { resolveProviderAuthAliasMap } from "../../agents/provider-auth-aliases.js";
|
||||
import { normalizeProviderIdForAuth } from "../../agents/provider-id.js";
|
||||
import type { OpenClawConfig } from "../../config/types.openclaw.js";
|
||||
@@ -65,7 +68,10 @@ export function createModelListAuthIndex(
|
||||
}
|
||||
|
||||
for (const provider of Object.keys(params.cfg.models?.providers ?? {})) {
|
||||
if (hasUsableCustomProviderApiKey(params.cfg, provider, env)) {
|
||||
if (
|
||||
hasUsableCustomProviderApiKey(params.cfg, provider, env) ||
|
||||
hasSyntheticLocalProviderAuthConfig({ cfg: params.cfg, provider })
|
||||
) {
|
||||
addProvider(provider);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,6 +209,7 @@ function installModelsListCommandForwardCompatMocks() {
|
||||
|
||||
vi.doMock("../../agents/model-auth.js", () => ({
|
||||
hasUsableCustomProviderApiKey: vi.fn().mockReturnValue(false),
|
||||
hasSyntheticLocalProviderAuthConfig: vi.fn().mockReturnValue(false),
|
||||
}));
|
||||
|
||||
vi.doMock("../../plugins/installed-plugin-index-store.js", () => ({
|
||||
|
||||
Reference in New Issue
Block a user