mirror of
https://github.com/farcasclaudiu/openclaw.git
synced 2026-06-28 19:01:47 +03:00
refactor(agents): dedupe model fallback candidate logic
This commit is contained in:
@@ -55,19 +55,10 @@ function shouldRethrowAbort(err: unknown): boolean {
|
|||||||
return isFallbackAbortError(err) && !isTimeoutError(err);
|
return isFallbackAbortError(err) && !isTimeoutError(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveImageFallbackCandidates(params: {
|
function createModelCandidateCollector(allowlist: Set<string> | null | undefined): {
|
||||||
cfg: OpenClawConfig | undefined;
|
candidates: ModelCandidate[];
|
||||||
defaultProvider: string;
|
addCandidate: (candidate: ModelCandidate, enforceAllowlist: boolean) => void;
|
||||||
modelOverride?: string;
|
} {
|
||||||
}): ModelCandidate[] {
|
|
||||||
const aliasIndex = buildModelAliasIndex({
|
|
||||||
cfg: params.cfg ?? {},
|
|
||||||
defaultProvider: params.defaultProvider,
|
|
||||||
});
|
|
||||||
const allowlist = buildConfiguredAllowlistKeys({
|
|
||||||
cfg: params.cfg,
|
|
||||||
defaultProvider: params.defaultProvider,
|
|
||||||
});
|
|
||||||
const seen = new Set<string>();
|
const seen = new Set<string>();
|
||||||
const candidates: ModelCandidate[] = [];
|
const candidates: ModelCandidate[] = [];
|
||||||
|
|
||||||
@@ -86,6 +77,39 @@ function resolveImageFallbackCandidates(params: {
|
|||||||
candidates.push(candidate);
|
candidates.push(candidate);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return { candidates, addCandidate };
|
||||||
|
}
|
||||||
|
|
||||||
|
type ModelFallbackErrorHandler = (attempt: {
|
||||||
|
provider: string;
|
||||||
|
model: string;
|
||||||
|
error: unknown;
|
||||||
|
attempt: number;
|
||||||
|
total: number;
|
||||||
|
}) => void | Promise<void>;
|
||||||
|
|
||||||
|
type ModelFallbackRunResult<T> = {
|
||||||
|
result: T;
|
||||||
|
provider: string;
|
||||||
|
model: string;
|
||||||
|
attempts: FallbackAttempt[];
|
||||||
|
};
|
||||||
|
|
||||||
|
function resolveImageFallbackCandidates(params: {
|
||||||
|
cfg: OpenClawConfig | undefined;
|
||||||
|
defaultProvider: string;
|
||||||
|
modelOverride?: string;
|
||||||
|
}): ModelCandidate[] {
|
||||||
|
const aliasIndex = buildModelAliasIndex({
|
||||||
|
cfg: params.cfg ?? {},
|
||||||
|
defaultProvider: params.defaultProvider,
|
||||||
|
});
|
||||||
|
const allowlist = buildConfiguredAllowlistKeys({
|
||||||
|
cfg: params.cfg,
|
||||||
|
defaultProvider: params.defaultProvider,
|
||||||
|
});
|
||||||
|
const { candidates, addCandidate } = createModelCandidateCollector(allowlist);
|
||||||
|
|
||||||
const addRaw = (raw: string, enforceAllowlist: boolean) => {
|
const addRaw = (raw: string, enforceAllowlist: boolean) => {
|
||||||
const resolved = resolveModelRefFromString({
|
const resolved = resolveModelRefFromString({
|
||||||
raw: String(raw ?? ""),
|
raw: String(raw ?? ""),
|
||||||
@@ -156,23 +180,7 @@ function resolveFallbackCandidates(params: {
|
|||||||
cfg: params.cfg,
|
cfg: params.cfg,
|
||||||
defaultProvider,
|
defaultProvider,
|
||||||
});
|
});
|
||||||
const seen = new Set<string>();
|
const { candidates, addCandidate } = createModelCandidateCollector(allowlist);
|
||||||
const candidates: ModelCandidate[] = [];
|
|
||||||
|
|
||||||
const addCandidate = (candidate: ModelCandidate, enforceAllowlist: boolean) => {
|
|
||||||
if (!candidate.provider || !candidate.model) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const key = modelKey(candidate.provider, candidate.model);
|
|
||||||
if (seen.has(key)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (enforceAllowlist && allowlist && !allowlist.has(key)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
seen.add(key);
|
|
||||||
candidates.push(candidate);
|
|
||||||
};
|
|
||||||
|
|
||||||
addCandidate(normalizedPrimary, false);
|
addCandidate(normalizedPrimary, false);
|
||||||
|
|
||||||
@@ -217,19 +225,8 @@ export async function runWithModelFallback<T>(params: {
|
|||||||
/** Optional explicit fallbacks list; when provided (even empty), replaces agents.defaults.model.fallbacks. */
|
/** Optional explicit fallbacks list; when provided (even empty), replaces agents.defaults.model.fallbacks. */
|
||||||
fallbacksOverride?: string[];
|
fallbacksOverride?: string[];
|
||||||
run: (provider: string, model: string) => Promise<T>;
|
run: (provider: string, model: string) => Promise<T>;
|
||||||
onError?: (attempt: {
|
onError?: ModelFallbackErrorHandler;
|
||||||
provider: string;
|
}): Promise<ModelFallbackRunResult<T>> {
|
||||||
model: string;
|
|
||||||
error: unknown;
|
|
||||||
attempt: number;
|
|
||||||
total: number;
|
|
||||||
}) => void | Promise<void>;
|
|
||||||
}): Promise<{
|
|
||||||
result: T;
|
|
||||||
provider: string;
|
|
||||||
model: string;
|
|
||||||
attempts: FallbackAttempt[];
|
|
||||||
}> {
|
|
||||||
const candidates = resolveFallbackCandidates({
|
const candidates = resolveFallbackCandidates({
|
||||||
cfg: params.cfg,
|
cfg: params.cfg,
|
||||||
provider: params.provider,
|
provider: params.provider,
|
||||||
@@ -335,19 +332,8 @@ export async function runWithImageModelFallback<T>(params: {
|
|||||||
cfg: OpenClawConfig | undefined;
|
cfg: OpenClawConfig | undefined;
|
||||||
modelOverride?: string;
|
modelOverride?: string;
|
||||||
run: (provider: string, model: string) => Promise<T>;
|
run: (provider: string, model: string) => Promise<T>;
|
||||||
onError?: (attempt: {
|
onError?: ModelFallbackErrorHandler;
|
||||||
provider: string;
|
}): Promise<ModelFallbackRunResult<T>> {
|
||||||
model: string;
|
|
||||||
error: unknown;
|
|
||||||
attempt: number;
|
|
||||||
total: number;
|
|
||||||
}) => void | Promise<void>;
|
|
||||||
}): Promise<{
|
|
||||||
result: T;
|
|
||||||
provider: string;
|
|
||||||
model: string;
|
|
||||||
attempts: FallbackAttempt[];
|
|
||||||
}> {
|
|
||||||
const candidates = resolveImageFallbackCandidates({
|
const candidates = resolveImageFallbackCandidates({
|
||||||
cfg: params.cfg,
|
cfg: params.cfg,
|
||||||
defaultProvider: DEFAULT_PROVIDER,
|
defaultProvider: DEFAULT_PROVIDER,
|
||||||
|
|||||||
Reference in New Issue
Block a user