feat: add fal and OpenRouter music generation (#82789)

* feat: add fal and OpenRouter music generation

* fix: repair music generation CI gates

* chore: refresh proof gate
This commit is contained in:
Peter Steinberger
2026-05-17 02:05:22 +01:00
committed by GitHub
parent 562d460d75
commit f453904165
54 changed files with 1535 additions and 87 deletions

View File

@@ -9,6 +9,8 @@ export type PluginCapabilityKind =
| "realtime-voice"
| "media-understanding"
| "image-generation"
| "video-generation"
| "music-generation"
| "web-search"
| "agent-harness"
| "context-engine"
@@ -44,6 +46,8 @@ function buildPluginCapabilityEntries(
{ kind: "realtime-voice" as const, ids: plugin.realtimeVoiceProviderIds },
{ kind: "media-understanding" as const, ids: plugin.mediaUnderstandingProviderIds },
{ kind: "image-generation" as const, ids: plugin.imageGenerationProviderIds },
{ kind: "video-generation" as const, ids: plugin.videoGenerationProviderIds },
{ kind: "music-generation" as const, ids: plugin.musicGenerationProviderIds },
{ kind: "web-search" as const, ids: plugin.webSearchProviderIds },
{ kind: "agent-harness" as const, ids: plugin.agentHarnessIds },
{

View File

@@ -502,7 +502,10 @@ export type PluginManifestProviderAuthChoice = {
onboardingScopes?: PluginManifestOnboardingScope[];
};
export type PluginManifestOnboardingScope = "text-inference" | "image-generation";
export type PluginManifestOnboardingScope =
| "text-inference"
| "image-generation"
| "music-generation";
export type PluginManifestLoadResult =
| { ok: true; manifest: PluginManifest; manifestPath: string }
@@ -1365,7 +1368,7 @@ function normalizeProviderAuthChoices(
const cliDescription = normalizeOptionalString(entry.cliDescription) ?? "";
const onboardingScopes = normalizeTrimmedStringList(entry.onboardingScopes).filter(
(scope): scope is PluginManifestOnboardingScope =>
scope === "text-inference" || scope === "image-generation",
scope === "text-inference" || scope === "image-generation" || scope === "music-generation",
);
normalized.push({
provider,

View File

@@ -26,7 +26,7 @@ export type OfficialExternalProviderAuthChoice = {
cliFlag?: string;
cliOption?: string;
cliDescription?: string;
onboardingScopes?: readonly ("text-inference" | "image-generation")[];
onboardingScopes?: readonly ("text-inference" | "image-generation" | "music-generation")[];
};
export type OfficialExternalProviderCatalogProvider = {

View File

@@ -24,7 +24,7 @@ export type ProviderAuthChoiceMetadata = {
cliFlag?: string;
cliOption?: string;
cliDescription?: string;
onboardingScopes?: ("text-inference" | "image-generation")[];
onboardingScopes?: ("text-inference" | "image-generation" | "music-generation")[];
};
export type ProviderOnboardAuthFlag = {

View File

@@ -262,13 +262,15 @@ function resolveProviderIndexInstallCatalogEntries(params: {
return entries;
}
function isProviderFlowScope(value: unknown): value is "text-inference" | "image-generation" {
return value === "text-inference" || value === "image-generation";
function isProviderFlowScope(
value: unknown,
): value is "text-inference" | "image-generation" | "music-generation" {
return value === "text-inference" || value === "image-generation" || value === "music-generation";
}
function normalizeProviderAuthChoiceScopes(
scopes: OfficialExternalProviderAuthChoice["onboardingScopes"],
): ("text-inference" | "image-generation")[] | undefined {
): ("text-inference" | "image-generation" | "music-generation")[] | undefined {
if (!Array.isArray(scopes)) {
return undefined;
}

View File

@@ -16,13 +16,15 @@ function normalizeTextList(values: string[] | undefined): string[] | undefined {
}
function normalizeOnboardingScopes(
values: Array<"text-inference" | "image-generation"> | undefined,
): Array<"text-inference" | "image-generation"> | undefined {
values: Array<"text-inference" | "image-generation" | "music-generation"> | undefined,
): Array<"text-inference" | "image-generation" | "music-generation"> | undefined {
const normalized = Array.from(
new Set(
(values ?? []).filter(
(value): value is "text-inference" | "image-generation" =>
value === "text-inference" || value === "image-generation",
(value): value is "text-inference" | "image-generation" | "music-generation" =>
value === "text-inference" ||
value === "image-generation" ||
value === "music-generation",
),
),
);

View File

@@ -24,7 +24,7 @@ export type ProviderWizardOption = {
groupId: string;
groupLabel: string;
groupHint?: string;
onboardingScopes?: Array<"text-inference" | "image-generation">;
onboardingScopes?: Array<"text-inference" | "image-generation" | "music-generation">;
assistantPriority?: number;
assistantVisibility?: "visible" | "manual-only";
onboardingFeatured?: boolean;

View File

@@ -1129,7 +1129,7 @@ export type ProviderPluginWizardSetup = {
* Interactive onboarding surfaces where this auth choice should appear.
* Defaults to `["text-inference"]` when omitted.
*/
onboardingScopes?: Array<"text-inference" | "image-generation">;
onboardingScopes?: Array<"text-inference" | "image-generation" | "music-generation">;
/**
* Optional model-allowlist prompt policy applied after this auth choice is
* selected in configure/onboarding flows.