mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-30 11:21:07 +00:00
refactor(plugins): register provider model id hooks
This commit is contained in:
@@ -25,6 +25,7 @@ let buildProviderAuthDoctorHintWithPlugin: typeof import("./provider-runtime.js"
|
||||
let buildProviderMissingAuthMessageWithPlugin: typeof import("./provider-runtime.js").buildProviderMissingAuthMessageWithPlugin;
|
||||
let buildProviderUnknownModelHintWithPlugin: typeof import("./provider-runtime.js").buildProviderUnknownModelHintWithPlugin;
|
||||
let formatProviderAuthProfileApiKeyWithPlugin: typeof import("./provider-runtime.js").formatProviderAuthProfileApiKeyWithPlugin;
|
||||
let normalizeProviderModelIdWithPlugin: typeof import("./provider-runtime.js").normalizeProviderModelIdWithPlugin;
|
||||
let prepareProviderExtraParams: typeof import("./provider-runtime.js").prepareProviderExtraParams;
|
||||
let resolveProviderStreamFn: typeof import("./provider-runtime.js").resolveProviderStreamFn;
|
||||
let resolveProviderCacheTtlEligibility: typeof import("./provider-runtime.js").resolveProviderCacheTtlEligibility;
|
||||
@@ -192,6 +193,7 @@ describe("provider-runtime", () => {
|
||||
buildProviderMissingAuthMessageWithPlugin,
|
||||
buildProviderUnknownModelHintWithPlugin,
|
||||
formatProviderAuthProfileApiKeyWithPlugin,
|
||||
normalizeProviderModelIdWithPlugin,
|
||||
prepareProviderExtraParams,
|
||||
resolveProviderStreamFn,
|
||||
resolveProviderCacheTtlEligibility,
|
||||
@@ -247,6 +249,34 @@ describe("provider-runtime", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("can normalize model ids through provider aliases without changing ownership", () => {
|
||||
resolvePluginProvidersMock.mockReturnValue([
|
||||
{
|
||||
id: "google",
|
||||
label: "Google",
|
||||
aliases: ["google-vertex"],
|
||||
auth: [],
|
||||
normalizeModelId: ({ modelId }) => modelId.replace("flash-lite", "flash-lite-preview"),
|
||||
},
|
||||
]);
|
||||
|
||||
expect(
|
||||
normalizeProviderModelIdWithPlugin({
|
||||
provider: "google-vertex",
|
||||
context: {
|
||||
provider: "google-vertex",
|
||||
modelId: "gemini-3.1-flash-lite",
|
||||
},
|
||||
}),
|
||||
).toBe("gemini-3.1-flash-lite-preview");
|
||||
expect(resolveOwningPluginIdsForProviderMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
provider: "google-vertex",
|
||||
}),
|
||||
);
|
||||
expect(resolvePluginProvidersMock).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("invalidates cached runtime providers when config mutates in place", () => {
|
||||
const config = {
|
||||
plugins: {
|
||||
@@ -342,6 +372,7 @@ describe("provider-runtime", () => {
|
||||
id: DEMO_PROVIDER_ID,
|
||||
label: "Demo",
|
||||
auth: [],
|
||||
normalizeModelId: ({ modelId }) => modelId.replace("-legacy", ""),
|
||||
resolveDynamicModel: () => MODEL,
|
||||
prepareDynamicModel,
|
||||
capabilities: {
|
||||
@@ -395,6 +426,16 @@ describe("provider-runtime", () => {
|
||||
}),
|
||||
).toMatchObject(MODEL);
|
||||
|
||||
expect(
|
||||
normalizeProviderModelIdWithPlugin({
|
||||
provider: DEMO_PROVIDER_ID,
|
||||
context: {
|
||||
provider: DEMO_PROVIDER_ID,
|
||||
modelId: "demo-model-legacy",
|
||||
},
|
||||
}),
|
||||
).toBe("demo-model");
|
||||
|
||||
await prepareProviderDynamicModel({
|
||||
provider: DEMO_PROVIDER_ID,
|
||||
context: createDemoRuntimeContext({
|
||||
|
||||
@@ -19,6 +19,7 @@ import type {
|
||||
ProviderCreateStreamFnContext,
|
||||
ProviderDefaultThinkingPolicyContext,
|
||||
ProviderFetchUsageSnapshotContext,
|
||||
ProviderNormalizeModelIdContext,
|
||||
ProviderModernModelPolicyContext,
|
||||
ProviderPrepareExtraParamsContext,
|
||||
ProviderPrepareDynamicModelContext,
|
||||
@@ -217,6 +218,25 @@ export function normalizeProviderResolvedModelWithPlugin(params: {
|
||||
);
|
||||
}
|
||||
|
||||
export function normalizeProviderModelIdWithPlugin(params: {
|
||||
provider: string;
|
||||
config?: OpenClawConfig;
|
||||
workspaceDir?: string;
|
||||
env?: NodeJS.ProcessEnv;
|
||||
context: ProviderNormalizeModelIdContext;
|
||||
}): string | undefined {
|
||||
const plugin =
|
||||
resolveProviderRuntimePlugin(params) ??
|
||||
resolveProviderPluginsForHooks({
|
||||
config: params.config,
|
||||
workspaceDir: params.workspaceDir,
|
||||
env: params.env,
|
||||
}).find((candidate) => matchesProviderId(candidate, params.provider));
|
||||
const normalized = plugin?.normalizeModelId?.(params.context);
|
||||
const trimmed = normalized?.trim();
|
||||
return trimmed ? trimmed : undefined;
|
||||
}
|
||||
|
||||
export function resolveProviderCapabilitiesWithPlugin(params: {
|
||||
provider: string;
|
||||
config?: OpenClawConfig;
|
||||
|
||||
@@ -363,6 +363,17 @@ export type ProviderNormalizeResolvedModelContext = {
|
||||
model: ProviderRuntimeModel;
|
||||
};
|
||||
|
||||
/**
|
||||
* Provider-owned model-id normalization before config/runtime lookup.
|
||||
*
|
||||
* Use this for provider-specific alias cleanup that should stay with the
|
||||
* plugin rather than in core string tables.
|
||||
*/
|
||||
export type ProviderNormalizeModelIdContext = {
|
||||
provider: string;
|
||||
modelId: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Runtime auth input for providers that need an extra exchange step before
|
||||
* inference. The incoming `apiKey` is the raw credential resolved from auth
|
||||
@@ -829,6 +840,13 @@ export type ProviderPlugin = {
|
||||
normalizeResolvedModel?: (
|
||||
ctx: ProviderNormalizeResolvedModelContext,
|
||||
) => ProviderRuntimeModel | null | undefined;
|
||||
/**
|
||||
* Provider-owned model-id normalization.
|
||||
*
|
||||
* Runs before model lookup/canonicalization. Use this for alias cleanup such
|
||||
* as provider-owned preview/legacy model ids.
|
||||
*/
|
||||
normalizeModelId?: (ctx: ProviderNormalizeModelIdContext) => string | null | undefined;
|
||||
/**
|
||||
* Static provider capability overrides consumed by shared transcript/tooling
|
||||
* logic.
|
||||
|
||||
Reference in New Issue
Block a user