mirror of https://github.com/openclaw/openclaw.git
Commands: lazy-load model picker provider runtime (#47536)
* Commands: lazy-load model picker provider runtime * Tests: cover model picker runtime boundary
This commit is contained in:
parent
630958749c
commit
438991b6a4
|
|
@ -0,0 +1,7 @@
|
|||
export {
|
||||
resolveProviderModelPickerEntries,
|
||||
resolveProviderPluginChoice,
|
||||
runProviderModelSelectedHook,
|
||||
} from "../plugins/provider-wizard.js";
|
||||
export { resolvePluginProviders } from "../plugins/providers.js";
|
||||
export { runProviderPluginAuthMethod } from "./auth-choice.apply.plugin-provider.js";
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import { describe, expect, it, vi } from "vitest";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import {
|
||||
applyModelAllowlist,
|
||||
|
|
@ -37,19 +37,13 @@ vi.mock("../agents/model-auth.js", () => ({
|
|||
const resolveProviderModelPickerEntries = vi.hoisted(() => vi.fn(() => []));
|
||||
const resolveProviderPluginChoice = vi.hoisted(() => vi.fn());
|
||||
const runProviderModelSelectedHook = vi.hoisted(() => vi.fn(async () => {}));
|
||||
vi.mock("../plugins/provider-wizard.js", () => ({
|
||||
const resolvePluginProviders = vi.hoisted(() => vi.fn(() => []));
|
||||
const runProviderPluginAuthMethod = vi.hoisted(() => vi.fn());
|
||||
vi.mock("./model-picker.runtime.js", () => ({
|
||||
resolveProviderModelPickerEntries,
|
||||
resolveProviderPluginChoice,
|
||||
runProviderModelSelectedHook,
|
||||
}));
|
||||
|
||||
const resolvePluginProviders = vi.hoisted(() => vi.fn(() => []));
|
||||
vi.mock("../plugins/providers.js", () => ({
|
||||
resolvePluginProviders,
|
||||
}));
|
||||
|
||||
const runProviderPluginAuthMethod = vi.hoisted(() => vi.fn());
|
||||
vi.mock("./auth-choice.apply.plugin-provider.js", () => ({
|
||||
runProviderPluginAuthMethod,
|
||||
}));
|
||||
|
||||
|
|
@ -77,6 +71,10 @@ function createSelectAllMultiselect() {
|
|||
return vi.fn(async (params) => params.options.map((option: { value: string }) => option.value));
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
describe("promptDefaultModel", () => {
|
||||
it("supports configuring vLLM during onboarding", async () => {
|
||||
loadModelCatalog.mockResolvedValue([
|
||||
|
|
@ -211,6 +209,7 @@ describe("router model filtering", () => {
|
|||
const allowlistCall = multiselect.mock.calls[0]?.[0];
|
||||
expectRouterModelFiltering(allowlistCall?.options as Array<{ value: string }>);
|
||||
expect(allowlistCall?.searchable).toBe(true);
|
||||
expect(runProviderPluginAuthMethod).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -11,14 +11,8 @@ import {
|
|||
} from "../agents/model-selection.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { resolveAgentModelPrimaryValue } from "../config/model-input.js";
|
||||
import {
|
||||
resolveProviderPluginChoice,
|
||||
resolveProviderModelPickerEntries,
|
||||
runProviderModelSelectedHook,
|
||||
} from "../plugins/provider-wizard.js";
|
||||
import { resolvePluginProviders } from "../plugins/providers.js";
|
||||
import type { ProviderPlugin } from "../plugins/types.js";
|
||||
import type { WizardPrompter, WizardSelectOption } from "../wizard/prompts.js";
|
||||
import { runProviderPluginAuthMethod } from "./auth-choice.apply.plugin-provider.js";
|
||||
import { formatTokenK } from "./models/shared.js";
|
||||
import { OPENAI_CODEX_DEFAULT_MODEL } from "./openai-codex-model-default.js";
|
||||
|
||||
|
|
@ -49,6 +43,10 @@ type PromptDefaultModelParams = {
|
|||
type PromptDefaultModelResult = { model?: string; config?: OpenClawConfig };
|
||||
type PromptModelAllowlistResult = { models?: string[] };
|
||||
|
||||
async function loadModelPickerRuntime() {
|
||||
return import("./model-picker.runtime.js");
|
||||
}
|
||||
|
||||
function hasAuthForProvider(
|
||||
provider: string,
|
||||
cfg: OpenClawConfig,
|
||||
|
|
@ -295,6 +293,7 @@ export async function promptDefaultModel(
|
|||
options.push({ value: MANUAL_VALUE, label: "Enter model manually" });
|
||||
}
|
||||
if (includeProviderPluginSetups && agentDir) {
|
||||
const { resolveProviderModelPickerEntries } = await loadModelPickerRuntime();
|
||||
options.push(
|
||||
...resolveProviderModelPickerEntries({
|
||||
config: cfg,
|
||||
|
|
@ -347,20 +346,24 @@ export async function promptDefaultModel(
|
|||
initialValue: configuredRaw || resolvedKey || undefined,
|
||||
});
|
||||
}
|
||||
const pluginProviders = resolvePluginProviders({
|
||||
config: cfg,
|
||||
workspaceDir: params.workspaceDir,
|
||||
env: params.env,
|
||||
});
|
||||
const pluginResolution = selection.startsWith("provider-plugin:")
|
||||
? selection
|
||||
: selection.includes("/")
|
||||
? null
|
||||
: pluginProviders.some(
|
||||
(provider) => normalizeProviderId(provider.id) === normalizeProviderId(selection),
|
||||
)
|
||||
? selection
|
||||
: null;
|
||||
|
||||
let pluginResolution: string | null = null;
|
||||
let pluginProviders: ProviderPlugin[] = [];
|
||||
if (selection.startsWith("provider-plugin:")) {
|
||||
pluginResolution = selection;
|
||||
} else if (!selection.includes("/")) {
|
||||
const { resolvePluginProviders } = await loadModelPickerRuntime();
|
||||
pluginProviders = resolvePluginProviders({
|
||||
config: cfg,
|
||||
workspaceDir: params.workspaceDir,
|
||||
env: params.env,
|
||||
});
|
||||
pluginResolution = pluginProviders.some(
|
||||
(provider) => normalizeProviderId(provider.id) === normalizeProviderId(selection),
|
||||
)
|
||||
? selection
|
||||
: null;
|
||||
}
|
||||
if (pluginResolution) {
|
||||
if (!agentDir || !params.runtime) {
|
||||
await params.prompter.note(
|
||||
|
|
@ -369,6 +372,19 @@ export async function promptDefaultModel(
|
|||
);
|
||||
return {};
|
||||
}
|
||||
const {
|
||||
resolvePluginProviders,
|
||||
resolveProviderPluginChoice,
|
||||
runProviderModelSelectedHook,
|
||||
runProviderPluginAuthMethod,
|
||||
} = await loadModelPickerRuntime();
|
||||
if (pluginProviders.length === 0) {
|
||||
pluginProviders = resolvePluginProviders({
|
||||
config: cfg,
|
||||
workspaceDir: params.workspaceDir,
|
||||
env: params.env,
|
||||
});
|
||||
}
|
||||
const resolved = resolveProviderPluginChoice({
|
||||
providers: pluginProviders,
|
||||
choice: pluginResolution,
|
||||
|
|
@ -397,6 +413,7 @@ export async function promptDefaultModel(
|
|||
return { model: applied.defaultModel, config: applied.config };
|
||||
}
|
||||
const model = String(selection);
|
||||
const { runProviderModelSelectedHook } = await loadModelPickerRuntime();
|
||||
await runProviderModelSelectedHook({
|
||||
config: cfg,
|
||||
model,
|
||||
|
|
|
|||
Loading…
Reference in New Issue