mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-03 05:26:24 +00:00
* Feat: LM Studio Integration * Format * Support usage in streaming true Fix token count * Add custom window check * Drop max tokens fallback * tweak docs Update generated * Avoid error if stale header does not resolve * Fix test * Fix test * Fix rebase issues Trim code * Fix tests Drop keyless Fixes * Fix linter issues in tests * Update generated artifacts * Do not have fatal header resoltuion for discovery * Do the same for API key as well * fix: honor lmstudio preload runtime auth * fix: clear stale lmstudio header auth * fix: lazy-load lmstudio runtime facade * fix: preserve lmstudio shared synthetic auth * fix: clear stale lmstudio header auth in discovery * fix: prefer lmstudio header auth for discovery * fix: honor lmstudio header auth in warmup paths * fix: clear stale lmstudio profile auth * fix: ignore lmstudio env auth on header migration * fix: use local lmstudio setup seam * fix: resolve lmstudio rebase fallout --------- Co-authored-by: Frank Yang <frank.ekn@gmail.com>
60 lines
1.9 KiB
TypeScript
60 lines
1.9 KiB
TypeScript
import {
|
|
CUSTOM_LOCAL_AUTH_MARKER,
|
|
hasConfiguredSecretInput,
|
|
normalizeOptionalSecretInput,
|
|
} from "openclaw/plugin-sdk/provider-auth";
|
|
import type { ModelProviderConfig } from "openclaw/plugin-sdk/provider-model-shared";
|
|
import { LMSTUDIO_LOCAL_API_KEY_PLACEHOLDER } from "./defaults.js";
|
|
|
|
export function hasLmstudioAuthorizationHeader(headers: unknown): boolean {
|
|
if (!headers || typeof headers !== "object" || Array.isArray(headers)) {
|
|
return false;
|
|
}
|
|
for (const [headerName, headerValue] of Object.entries(headers)) {
|
|
if (headerName.trim().toLowerCase() !== "authorization") {
|
|
continue;
|
|
}
|
|
if (hasConfiguredSecretInput(headerValue)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
export function resolveLmstudioProviderAuthMode(
|
|
apiKey: ModelProviderConfig["apiKey"] | undefined,
|
|
): ModelProviderConfig["auth"] | undefined {
|
|
const normalized = normalizeOptionalSecretInput(apiKey);
|
|
if (normalized !== undefined) {
|
|
const trimmed = normalized.trim();
|
|
if (
|
|
!trimmed ||
|
|
trimmed === LMSTUDIO_LOCAL_API_KEY_PLACEHOLDER ||
|
|
trimmed === CUSTOM_LOCAL_AUTH_MARKER
|
|
) {
|
|
return undefined;
|
|
}
|
|
return "api-key";
|
|
}
|
|
return hasConfiguredSecretInput(apiKey) ? "api-key" : undefined;
|
|
}
|
|
|
|
export function shouldUseLmstudioApiKeyPlaceholder(params: {
|
|
hasModels: boolean;
|
|
resolvedApiKey: ModelProviderConfig["apiKey"] | undefined;
|
|
hasAuthorizationHeader?: boolean;
|
|
}): boolean {
|
|
return params.hasModels && !params.resolvedApiKey && !params.hasAuthorizationHeader;
|
|
}
|
|
|
|
export function shouldUseLmstudioSyntheticAuth(
|
|
providerConfig: ModelProviderConfig | undefined,
|
|
): boolean {
|
|
const hasModels = Array.isArray(providerConfig?.models) && providerConfig.models.length > 0;
|
|
return (
|
|
hasModels &&
|
|
!resolveLmstudioProviderAuthMode(providerConfig?.apiKey) &&
|
|
!hasLmstudioAuthorizationHeader(providerConfig?.headers)
|
|
);
|
|
}
|