

























@@ -27,6 +27,10 @@ import {
2727describeImagesWithModel,
2828type MediaUnderstandingProvider,
2929} from "../../plugin-sdk/media-understanding.js";
30+import {
31+isManifestPluginAvailableForControlPlane,
32+loadManifestMetadataSnapshot,
33+} from "../../plugins/manifest-contract-eligibility.js";
3034import type { ProviderRuntimeModel } from "../../plugins/provider-runtime-model.types.js";
3135import { resolveUserPath } from "../../utils.js";
3236import type { AuthProfileStore } from "../auth-profiles/types.js";
@@ -309,6 +313,115 @@ function resolveCompressionModelCandidates(params: {
309313});
310314}
311315316+function imageCompressionPolicyHasDimensionLimit(policy: ImageCompressionModelPolicy): boolean {
317+return (
318+typeof policy.maxSidePx === "number" ||
319+typeof policy.maxPixels === "number"
320+);
321+}
322+323+function mergeImageCompressionPolicies(params: {
324+runtimePolicy: ImageCompressionModelPolicy;
325+staticPolicy: ImageCompressionModelPolicy;
326+}): ImageCompressionModelPolicy {
327+return {
328+ ...params.runtimePolicy,
329+ ...params.staticPolicy,
330+};
331+}
332+333+function providerUsesRuntimeModelAugment(params: {
334+cfg?: OpenClawConfig;
335+provider: string;
336+workspaceDir?: string;
337+}): boolean {
338+const provider = normalizeMediaProviderId(params.provider);
339+if (!provider) {
340+return false;
341+}
342+const config = params.cfg ?? {};
343+const snapshot = loadManifestMetadataSnapshot({
344+ config,
345+env: process.env,
346+ ...(params.workspaceDir !== undefined ? { workspaceDir: params.workspaceDir } : {}),
347+});
348+return snapshot.plugins.some((plugin) => {
349+const ownsProvider =
350+plugin.providers.some((candidate) => normalizeMediaProviderId(candidate) === provider) ||
351+Boolean(plugin.modelCatalog?.providers?.[provider]);
352+if (!ownsProvider) {
353+return false;
354+}
355+const runtimeAugment =
356+plugin.modelCatalog?.runtimeAugment === true ||
357+(plugin.origin !== "bundled" &&
358+plugin.providers.some((candidate) => normalizeMediaProviderId(candidate) === provider));
359+if (!runtimeAugment) {
360+return false;
361+}
362+return isManifestPluginAvailableForControlPlane({
363+ snapshot,
364+ plugin,
365+ config,
366+});
367+});
368+}
369+370+async function resolveCompressionModelPolicyWithHooks(params: {
371+cfg?: OpenClawConfig;
372+provider: string;
373+model: string;
374+agentDir?: string;
375+workspaceDir?: string;
376+skipProviderRuntimeHooks: boolean;
377+}): Promise<ImageCompressionModelPolicy> {
378+try {
379+const resolved = await resolveModelAsync(
380+params.provider,
381+params.model,
382+params.agentDir,
383+params.cfg,
384+{
385+allowBundledStaticCatalogFallback: true,
386+skipProviderRuntimeHooks: params.skipProviderRuntimeHooks,
387+skipPiDiscovery: true,
388+workspaceDir: params.workspaceDir,
389+},
390+);
391+return (resolved.model as ProviderRuntimeModel | undefined)?.mediaInput?.image ?? {};
392+} catch {
393+return {};
394+}
395+}
396+397+async function resolveCompressionModelPolicy(params: {
398+cfg?: OpenClawConfig;
399+provider: string;
400+model: string;
401+agentDir?: string;
402+workspaceDir?: string;
403+}): Promise<ImageCompressionModelPolicy> {
404+const staticPolicy = await resolveCompressionModelPolicyWithHooks({
405+ ...params,
406+skipProviderRuntimeHooks: true,
407+});
408+if (
409+imageCompressionPolicyHasDimensionLimit(staticPolicy) ||
410+!providerUsesRuntimeModelAugment({
411+cfg: params.cfg,
412+provider: params.provider,
413+workspaceDir: params.workspaceDir,
414+})
415+) {
416+return staticPolicy;
417+}
418+const runtimePolicy = await resolveCompressionModelPolicyWithHooks({
419+ ...params,
420+skipProviderRuntimeHooks: false,
421+});
422+return mergeImageCompressionPolicies({ runtimePolicy, staticPolicy });
423+}
424+312425async function resolveImageCompressionPolicy(params: {
313426cfg?: OpenClawConfig;
314427imageModelConfig?: ImageModelConfig | null;
@@ -321,22 +434,13 @@ async function resolveImageCompressionPolicy(params: {
321434const quality = params.cfg?.agents?.defaults?.imageQuality;
322435const models: ImageCompressionModelPolicy[] = await Promise.all(
323436modelCandidates.map(async (candidate): Promise<ImageCompressionModelPolicy> => {
324-try {
325-const resolved = await resolveModelAsync(
326-candidate.provider,
327-candidate.model,
328-params.agentDir,
329-params.cfg,
330-{
331-allowBundledStaticCatalogFallback: true,
332-skipPiDiscovery: true,
333-workspaceDir: params.workspaceDir,
334-},
335-);
336-return (resolved.model as ProviderRuntimeModel | undefined)?.mediaInput?.image ?? {};
337-} catch {
338-return {};
339-}
437+return resolveCompressionModelPolicy({
438+cfg: params.cfg,
439+provider: candidate.provider,
440+model: candidate.model,
441+agentDir: params.agentDir,
442+workspaceDir: params.workspaceDir,
443+});
340444}),
341445);
342446return {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。