






















@@ -33,13 +33,13 @@ export const MEDIA_SUITES: Record<MediaSuiteId, MediaSuiteConfig> = {
3333id: "image",
3434testFile: "test/image-generation.runtime.live.test.ts",
3535providerEnvVar: "OPENCLAW_LIVE_IMAGE_GENERATION_PROVIDERS",
36-providers: ["deepinfra", "fal", "google", "minimax", "openai", "vydra", "xai"],
36+providers: ["deepinfra", "fal", "google", "minimax", "openai", "openrouter", "vydra", "xai"],
3737},
3838music: {
3939id: "music",
4040testFile: "extensions/music-generation-providers.live.test.ts",
4141providerEnvVar: "OPENCLAW_LIVE_MUSIC_GENERATION_PROVIDERS",
42-providers: ["google", "minimax"],
42+providers: ["fal", "google", "minimax", "openrouter"],
4343},
4444video: {
4545id: "video",
@@ -53,6 +53,7 @@ export const MEDIA_SUITES: Record<MediaSuiteId, MediaSuiteConfig> = {
5353"google",
5454"minimax",
5555"openai",
56+"openrouter",
5657"qwen",
5758"runway",
5859"together",
@@ -66,6 +67,7 @@ export const MEDIA_SUITES: Record<MediaSuiteId, MediaSuiteConfig> = {
6667"google",
6768"minimax",
6869"openai",
70+"openrouter",
6971"qwen",
7072"runway",
7173"together",
@@ -93,6 +95,10 @@ export type SuiteRunPlan = {
9395skippedReason?: string;
9496};
959798+function formatProviderList(providers: Iterable<string>): string {
99+return [...providers].toSorted().join(", ");
100+}
101+96102function spawnLivePnpm(params: { pnpmArgs: string[]; env: NodeJS.ProcessEnv }): ChildProcess {
97103return _spawnPnpmRunner({
98104pnpmArgs: params.pnpmArgs,
@@ -204,7 +210,7 @@ export function parseArgs(argv: string[]): CliOptions {
204210throw new Error(`Unknown argument: ${arg}`);
205211 }
206212207- return {
213+ const options = {
208214 suites: (suites.size ? [...suites] : DEFAULT_SUITES).toSorted(),
209215 globalProviders,
210216 suiteProviders,
@@ -213,6 +219,40 @@ export function parseArgs(argv: string[]): CliOptions {
213219 passthroughArgs: [...passthroughArgs, ...separatorPassthroughArgs],
214220 help,
215221 };
222+ validateProviderFilters(options);
223+ return options;
224+}
225+226+function validateProviderFilters(options: CliOptions): void {
227+ if (options.globalProviders) {
228+ const selectedProviders = new Set(
229+ options.suites.flatMap((suiteId) => MEDIA_SUITES[suiteId].providers),
230+ );
231+ const unknown = [...options.globalProviders].filter(
232+ (provider) => !selectedProviders.has(provider),
233+ );
234+ if (unknown.length > 0) {
235+ throw new Error(
236+ `Unknown provider(s) for selected media suite(s): ${formatProviderList(unknown)}`,
237+ );
238+ }
239+ }
240+241+ for (const [suiteId, providers] of Object.entries(options.suiteProviders) as [
242+ MediaSuiteId,
243+ Set<string>,
244+ ][]) {
245+ const suite = MEDIA_SUITES[suiteId];
246+ const supported = new Set(suite.providers);
247+ const unknown = [...providers].filter((provider) => !supported.has(provider));
248+ if (unknown.length > 0) {
249+ throw new Error(`Unknown ${suiteId} provider(s): ${formatProviderList(unknown)}`);
250+ }
251+ }
252+}
253+254+function hasExplicitProviderSelection(options: CliOptions): boolean {
255+ return options.globalProviders !== null || Object.keys(options.suiteProviders).length > 0;
216256}
217257218258function selectProviders(params: {
@@ -357,6 +397,10 @@ export async function runCli(argv: string[]): Promise<number> {
357397}
358398if (runnable.length === 0) {
359399console.log("[live:media] nothing to run");
400+if (hasExplicitProviderSelection(options)) {
401+console.error("[live:media] no runnable providers matched the explicit provider selection");
402+return 1;
403+}
360404return 0;
361405}
362406此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。