mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-06 05:51:15 +08:00
perf(agents): avoid full setup registry for runtime aliases
This commit is contained in:
@@ -232,6 +232,33 @@ export function listCliRuntimeProviderIds(
|
||||
].toSorted();
|
||||
}
|
||||
|
||||
export function resolveCliRuntimeCanonicalProvider(params: {
|
||||
runtime: string | undefined;
|
||||
config?: OpenClawConfig;
|
||||
env?: NodeJS.ProcessEnv;
|
||||
includeSetupRegistry?: boolean;
|
||||
}): string | undefined {
|
||||
const runtime = normalizeBackendKey(params.runtime ?? "");
|
||||
if (!runtime) {
|
||||
return undefined;
|
||||
}
|
||||
const runtimeBinding = listCliRuntimeModelBackendBindings().find(
|
||||
(binding) => binding.runtime === runtime,
|
||||
);
|
||||
if (runtimeBinding) {
|
||||
return runtimeBinding.provider;
|
||||
}
|
||||
if (params.includeSetupRegistry !== true) {
|
||||
return undefined;
|
||||
}
|
||||
const setupBackend = cliBackendsDeps.resolvePluginSetupCliBackend({
|
||||
backend: runtime,
|
||||
config: params.config,
|
||||
env: params.env,
|
||||
});
|
||||
return setupBackend ? resolveCliBackendModelProvider(setupBackend.backend) : undefined;
|
||||
}
|
||||
|
||||
export function resolveCliRuntimeModelBackendBinding(params: {
|
||||
provider: string | undefined;
|
||||
runtime: string | undefined;
|
||||
@@ -253,11 +280,22 @@ export function resolveCliRuntimeModelBackendBinding(params: {
|
||||
if (!includeSetupRegistry) {
|
||||
return undefined;
|
||||
}
|
||||
return listCliRuntimeModelBackendBindings({
|
||||
const setupBackend = cliBackendsDeps.resolvePluginSetupCliBackend({
|
||||
backend: runtime,
|
||||
config: params.config,
|
||||
env: params.env,
|
||||
includeSetupRegistry: true,
|
||||
}).find((binding) => binding.provider === provider && binding.runtime === runtime);
|
||||
});
|
||||
if (!setupBackend) {
|
||||
return undefined;
|
||||
}
|
||||
const setupProvider = resolveCliBackendModelProvider(setupBackend.backend);
|
||||
return setupProvider === provider
|
||||
? {
|
||||
provider,
|
||||
runtime,
|
||||
...(setupBackend.pluginId ? { pluginId: setupBackend.pluginId } : {}),
|
||||
}
|
||||
: undefined;
|
||||
}
|
||||
|
||||
export function isCliRuntimeModelBackendForProvider(params: {
|
||||
|
||||
@@ -185,4 +185,39 @@ describe("areRuntimeModelRefsEquivalent", () => {
|
||||
}),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("resolves one setup runtime alias without loading the full setup registry", () => {
|
||||
cliBackendsTesting.setDepsForTest({
|
||||
resolvePluginSetupCliBackend: ({ backend }) =>
|
||||
backend === "claude-cli"
|
||||
? {
|
||||
pluginId: "anthropic",
|
||||
backend: {
|
||||
id: "claude-cli",
|
||||
modelProvider: "anthropic",
|
||||
config: { command: "claude" },
|
||||
bundleMcp: false,
|
||||
},
|
||||
}
|
||||
: undefined,
|
||||
resolvePluginSetupRegistry: () => {
|
||||
throw new Error("setup registry should not load for a single runtime alias");
|
||||
},
|
||||
resolveRuntimeCliBackends: () => [],
|
||||
});
|
||||
|
||||
expect(
|
||||
areRuntimeModelRefsEquivalent("anthropic/claude-opus-4-7", "claude-cli/claude-opus-4-7", {
|
||||
config: {
|
||||
agents: {
|
||||
defaults: {
|
||||
cliBackends: {
|
||||
"claude-cli": { command: "claude" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
isCliRuntimeModelBackendForProvider,
|
||||
listCliRuntimeModelBackendBindings,
|
||||
listCliRuntimeProviderIds,
|
||||
resolveCliRuntimeCanonicalProvider,
|
||||
resolveCliRuntimeModelBackendBinding,
|
||||
} from "./cli-backends.js";
|
||||
import { resolveModelRuntimePolicy } from "./model-runtime-policy.js";
|
||||
@@ -53,14 +54,14 @@ function canonicalizeRuntimeAliasProvider(
|
||||
provider: string,
|
||||
options: RuntimeAliasComparisonOptions = {},
|
||||
): string {
|
||||
const normalized = normalizeProviderId(provider);
|
||||
return (
|
||||
listCliRuntimeModelBackendBindings({
|
||||
resolveCliRuntimeCanonicalProvider({
|
||||
runtime: provider,
|
||||
config: options.config,
|
||||
env: options.env,
|
||||
includeSetupRegistry:
|
||||
options.includeSetupRegistry ?? (options.config !== undefined || options.env !== undefined),
|
||||
}).find((binding) => binding.runtime === normalized)?.provider ?? provider
|
||||
}) ?? provider
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -155,6 +155,7 @@ describe("fallback-state", () => {
|
||||
fallbackNoticeActiveModel: "claude-cli/claude-opus-4-7",
|
||||
fallbackNoticeReason: "selected model unavailable",
|
||||
},
|
||||
cfg: {},
|
||||
});
|
||||
|
||||
expect(resolved.fallbackActive).toBe(false);
|
||||
@@ -164,6 +165,47 @@ describe("fallback-state", () => {
|
||||
expect(resolved.nextState.activeModel).toBeUndefined();
|
||||
});
|
||||
|
||||
it("does not repeat runtime alias comparison when persisted fallback refs match", () => {
|
||||
let setupBackendLookups = 0;
|
||||
cliBackendsTesting.setDepsForTest({
|
||||
resolvePluginSetupCliBackend: ({ backend }) => {
|
||||
setupBackendLookups += 1;
|
||||
return backend === "claude-cli"
|
||||
? {
|
||||
pluginId: "anthropic",
|
||||
backend: {
|
||||
id: "claude-cli",
|
||||
modelProvider: "anthropic",
|
||||
config: { command: "claude" },
|
||||
bundleMcp: false,
|
||||
},
|
||||
}
|
||||
: undefined;
|
||||
},
|
||||
resolvePluginSetupRegistry: () => {
|
||||
throw new Error("full setup registry should not load for a single runtime alias");
|
||||
},
|
||||
resolveRuntimeCliBackends: () => [],
|
||||
});
|
||||
|
||||
const resolved = resolveFallbackTransition({
|
||||
selectedProvider: "anthropic",
|
||||
selectedModel: "claude-opus-4-7",
|
||||
activeProvider: "claude-cli",
|
||||
activeModel: "claude-opus-4-7",
|
||||
attempts: [],
|
||||
state: {
|
||||
fallbackNoticeSelectedModel: "anthropic/claude-opus-4-7",
|
||||
fallbackNoticeActiveModel: "claude-cli/claude-opus-4-7",
|
||||
fallbackNoticeReason: "selected model unavailable",
|
||||
},
|
||||
cfg: {},
|
||||
});
|
||||
|
||||
expect(resolved.fallbackActive).toBe(false);
|
||||
expect(setupBackendLookups).toBe(2);
|
||||
});
|
||||
|
||||
it("does not build a fallback notice for equivalent CLI runtime aliases", () => {
|
||||
registerAnthropicCliBackendForTest();
|
||||
|
||||
|
||||
@@ -166,15 +166,20 @@ export function resolveFallbackTransition(params: {
|
||||
fallbackActive &&
|
||||
(previousState.selectedModel !== selectedModelRef ||
|
||||
previousState.activeModel !== activeModelRef);
|
||||
const previousStateWasRealFallback = Boolean(
|
||||
previousState.selectedModel &&
|
||||
previousState.activeModel &&
|
||||
!areRuntimeModelRefsEquivalent(
|
||||
previousState.selectedModel,
|
||||
previousState.activeModel,
|
||||
comparisonOptions,
|
||||
),
|
||||
);
|
||||
const previousStateMatchesCurrent =
|
||||
previousState.selectedModel === selectedModelRef &&
|
||||
previousState.activeModel === activeModelRef;
|
||||
const previousStateWasRealFallback = previousStateMatchesCurrent
|
||||
? fallbackActive
|
||||
: Boolean(
|
||||
previousState.selectedModel &&
|
||||
previousState.activeModel &&
|
||||
!areRuntimeModelRefsEquivalent(
|
||||
previousState.selectedModel,
|
||||
previousState.activeModel,
|
||||
comparisonOptions,
|
||||
),
|
||||
);
|
||||
const fallbackCleared = !fallbackActive && previousStateWasRealFallback;
|
||||
const reasonSummary = buildFallbackReasonSummary(params.attempts);
|
||||
const attemptSummaries = buildFallbackAttemptSummaries(params.attempts);
|
||||
|
||||
Reference in New Issue
Block a user