Vendor OpenClaw source as Adolf fork baseline
Some checks failed
ClawSweeper Dispatch / dispatch (push) Has been cancelled
CodeQL / Security High (actions) (push) Has been cancelled
CodeQL / Security High (channel-runtime-boundary) (push) Has been cancelled
CodeQL / Security High (core-auth-secrets) (push) Has been cancelled
CodeQL / Security High (mcp-process-tool-boundary) (push) Has been cancelled
CodeQL / Security High (network-ssrf-boundary) (push) Has been cancelled
CodeQL / Security High (plugin-trust-boundary) (push) Has been cancelled
CodeQL / Security High (process-exec-boundary) (push) Has been cancelled
Docs Sync Publish Repo / sync-publish-repo (push) Has been cancelled
Docs / docs (push) Has been cancelled
OpenClaw Stable Main Closeout / Resolve stable release closeout inputs (push) Has been cancelled
OpenClaw Stable Main Closeout / Verify stable main closeout (push) Has been cancelled
Workflow Sanity / no-tabs (push) Has been cancelled
Workflow Sanity / actionlint (push) Has been cancelled
Workflow Sanity / generated-doc-baselines (push) Has been cancelled
CI / runner-admission (push) Has been cancelled
CI / preflight (push) Has been cancelled
CI / security-fast (push) Has been cancelled
CI / pnpm-store-warmup (push) Has been cancelled
CI / build-artifacts (push) Has been cancelled
CI / native-i18n (push) Has been cancelled
CI / ${{ matrix.check_name }} (push) Has been cancelled
CI / ${{ matrix.checkName }} (push) Has been cancelled
CI / checks-node-compat-node22 (push) Has been cancelled
CI / check-bundled-channel-config-metadata (push) Has been cancelled
CI / check-dependencies (push) Has been cancelled
CI / check-guards (push) Has been cancelled
CI / check-lint (push) Has been cancelled
CI / check-prod-types (push) Has been cancelled
CI / check-shrinkwrap (push) Has been cancelled
CI / check-test-types (push) Has been cancelled
CI / check-additional-boundaries-a (push) Has been cancelled
CI / check-additional-boundaries-bcd (push) Has been cancelled
CI / check-additional-extension-bundled (push) Has been cancelled
CI / check-additional-extension-channels (push) Has been cancelled
CI / check-additional-extension-package-boundary (push) Has been cancelled
CI / check-additional-runtime-topology-architecture (push) Has been cancelled
CI / check-session-accessor-boundary (push) Has been cancelled
CI / check-session-transcript-reader-boundary (push) Has been cancelled
CI / check-docs (push) Has been cancelled
CI / skills-python (push) Has been cancelled
CI / macos-swift (push) Has been cancelled
CI / ios-build (push) Has been cancelled
CI / ci-timings-summary (push) Has been cancelled
Native App Locale Refresh / Refresh native fa (push) Has been cancelled
Native App Locale Refresh / Refresh native fr (push) Has been cancelled
Native App Locale Refresh / Refresh native hi (push) Has been cancelled
Native App Locale Refresh / Refresh native id (push) Has been cancelled
Native App Locale Refresh / Refresh native it (push) Has been cancelled
Native App Locale Refresh / Refresh native ja-JP (push) Has been cancelled
Control UI Locale Refresh / plan (push) Has been cancelled
Control UI Locale Refresh / Refresh ${{ matrix.locale }} (push) Has been cancelled
Control UI Locale Refresh / Commit control UI locale refresh (push) Has been cancelled
Live Media Runner Image / Build live media runner image (push) Has been cancelled
Native App Locale Refresh / Refresh native ar (push) Has been cancelled
Native App Locale Refresh / Refresh native de (push) Has been cancelled
Native App Locale Refresh / Refresh native es (push) Has been cancelled
Native App Locale Refresh / Refresh native ko (push) Has been cancelled
Native App Locale Refresh / Refresh native nl (push) Has been cancelled
Native App Locale Refresh / Refresh native pl (push) Has been cancelled
Native App Locale Refresh / Refresh native pt-BR (push) Has been cancelled
Native App Locale Refresh / Refresh native ru (push) Has been cancelled
Native App Locale Refresh / Refresh native sv (push) Has been cancelled
Native App Locale Refresh / Refresh native th (push) Has been cancelled
Native App Locale Refresh / Refresh native tr (push) Has been cancelled
Native App Locale Refresh / Refresh native uk (push) Has been cancelled
Native App Locale Refresh / Refresh native vi (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-CN (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-TW (push) Has been cancelled
Native App Locale Refresh / Commit native locale refresh (push) Has been cancelled
Plugin Init Scaffold Validation / Validate provider scaffold (push) Has been cancelled
Plugin NPM Release / preview_plugins_npm (push) Has been cancelled
Plugin NPM Release / Validate release publish approval (push) Has been cancelled
Plugin NPM Release / preview_plugin_pack (push) Has been cancelled
Plugin NPM Release / publish_plugins_npm (push) Has been cancelled
Sandbox Common Smoke / sandbox-common-smoke (push) Has been cancelled
Website Installer Sync / static (push) Has been cancelled
Website Installer Sync / linux-docker (push) Has been cancelled
Website Installer Sync / macos-installer (push) Has been cancelled
Website Installer Sync / windows-installer (push) Has been cancelled
Website Installer Sync / sync-website (push) Has been cancelled
Some checks failed
ClawSweeper Dispatch / dispatch (push) Has been cancelled
CodeQL / Security High (actions) (push) Has been cancelled
CodeQL / Security High (channel-runtime-boundary) (push) Has been cancelled
CodeQL / Security High (core-auth-secrets) (push) Has been cancelled
CodeQL / Security High (mcp-process-tool-boundary) (push) Has been cancelled
CodeQL / Security High (network-ssrf-boundary) (push) Has been cancelled
CodeQL / Security High (plugin-trust-boundary) (push) Has been cancelled
CodeQL / Security High (process-exec-boundary) (push) Has been cancelled
Docs Sync Publish Repo / sync-publish-repo (push) Has been cancelled
Docs / docs (push) Has been cancelled
OpenClaw Stable Main Closeout / Resolve stable release closeout inputs (push) Has been cancelled
OpenClaw Stable Main Closeout / Verify stable main closeout (push) Has been cancelled
Workflow Sanity / no-tabs (push) Has been cancelled
Workflow Sanity / actionlint (push) Has been cancelled
Workflow Sanity / generated-doc-baselines (push) Has been cancelled
CI / runner-admission (push) Has been cancelled
CI / preflight (push) Has been cancelled
CI / security-fast (push) Has been cancelled
CI / pnpm-store-warmup (push) Has been cancelled
CI / build-artifacts (push) Has been cancelled
CI / native-i18n (push) Has been cancelled
CI / ${{ matrix.check_name }} (push) Has been cancelled
CI / ${{ matrix.checkName }} (push) Has been cancelled
CI / checks-node-compat-node22 (push) Has been cancelled
CI / check-bundled-channel-config-metadata (push) Has been cancelled
CI / check-dependencies (push) Has been cancelled
CI / check-guards (push) Has been cancelled
CI / check-lint (push) Has been cancelled
CI / check-prod-types (push) Has been cancelled
CI / check-shrinkwrap (push) Has been cancelled
CI / check-test-types (push) Has been cancelled
CI / check-additional-boundaries-a (push) Has been cancelled
CI / check-additional-boundaries-bcd (push) Has been cancelled
CI / check-additional-extension-bundled (push) Has been cancelled
CI / check-additional-extension-channels (push) Has been cancelled
CI / check-additional-extension-package-boundary (push) Has been cancelled
CI / check-additional-runtime-topology-architecture (push) Has been cancelled
CI / check-session-accessor-boundary (push) Has been cancelled
CI / check-session-transcript-reader-boundary (push) Has been cancelled
CI / check-docs (push) Has been cancelled
CI / skills-python (push) Has been cancelled
CI / macos-swift (push) Has been cancelled
CI / ios-build (push) Has been cancelled
CI / ci-timings-summary (push) Has been cancelled
Native App Locale Refresh / Refresh native fa (push) Has been cancelled
Native App Locale Refresh / Refresh native fr (push) Has been cancelled
Native App Locale Refresh / Refresh native hi (push) Has been cancelled
Native App Locale Refresh / Refresh native id (push) Has been cancelled
Native App Locale Refresh / Refresh native it (push) Has been cancelled
Native App Locale Refresh / Refresh native ja-JP (push) Has been cancelled
Control UI Locale Refresh / plan (push) Has been cancelled
Control UI Locale Refresh / Refresh ${{ matrix.locale }} (push) Has been cancelled
Control UI Locale Refresh / Commit control UI locale refresh (push) Has been cancelled
Live Media Runner Image / Build live media runner image (push) Has been cancelled
Native App Locale Refresh / Refresh native ar (push) Has been cancelled
Native App Locale Refresh / Refresh native de (push) Has been cancelled
Native App Locale Refresh / Refresh native es (push) Has been cancelled
Native App Locale Refresh / Refresh native ko (push) Has been cancelled
Native App Locale Refresh / Refresh native nl (push) Has been cancelled
Native App Locale Refresh / Refresh native pl (push) Has been cancelled
Native App Locale Refresh / Refresh native pt-BR (push) Has been cancelled
Native App Locale Refresh / Refresh native ru (push) Has been cancelled
Native App Locale Refresh / Refresh native sv (push) Has been cancelled
Native App Locale Refresh / Refresh native th (push) Has been cancelled
Native App Locale Refresh / Refresh native tr (push) Has been cancelled
Native App Locale Refresh / Refresh native uk (push) Has been cancelled
Native App Locale Refresh / Refresh native vi (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-CN (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-TW (push) Has been cancelled
Native App Locale Refresh / Commit native locale refresh (push) Has been cancelled
Plugin Init Scaffold Validation / Validate provider scaffold (push) Has been cancelled
Plugin NPM Release / preview_plugins_npm (push) Has been cancelled
Plugin NPM Release / Validate release publish approval (push) Has been cancelled
Plugin NPM Release / preview_plugin_pack (push) Has been cancelled
Plugin NPM Release / publish_plugins_npm (push) Has been cancelled
Sandbox Common Smoke / sandbox-common-smoke (push) Has been cancelled
Website Installer Sync / static (push) Has been cancelled
Website Installer Sync / linux-docker (push) Has been cancelled
Website Installer Sync / macos-installer (push) Has been cancelled
Website Installer Sync / windows-installer (push) Has been cancelled
Website Installer Sync / sync-website (push) Has been cancelled
Adolf is a fork/vendored clone of github.com/openclaw/openclaw (v2026.6.11), free to diverge. Tree copied sans upstream .git; upstream remote added for future syncs. Node pinned to 24 (.nvmrc); engines already require >=22.19. Preserves docs/ARCHITECTURE.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LeqyaxJF2nbRXJtae2kNB2
This commit is contained in:
204
extensions/fal/music-generation-provider.ts
Normal file
204
extensions/fal/music-generation-provider.ts
Normal file
@@ -0,0 +1,204 @@
|
||||
// Fal provider module implements model/runtime integration.
|
||||
import {
|
||||
downloadGeneratedMusicAsset,
|
||||
extractGeneratedMusicFileCandidates,
|
||||
type MusicGenerationProvider,
|
||||
type MusicGenerationRequest,
|
||||
} from "openclaw/plugin-sdk/music-generation";
|
||||
import { isProviderApiKeyConfigured } from "openclaw/plugin-sdk/provider-auth";
|
||||
import {
|
||||
assertOkOrThrowHttpError,
|
||||
postJsonRequest,
|
||||
readProviderJsonResponse,
|
||||
} from "openclaw/plugin-sdk/provider-http";
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { resolveFalHttpRequestConfig } from "./http-config.js";
|
||||
|
||||
const DEFAULT_FAL_MUSIC_MODEL = "fal-ai/minimax-music/v2.6";
|
||||
const FAL_ACE_STEP_MODEL = "fal-ai/ace-step/prompt-to-audio";
|
||||
const FAL_STABLE_AUDIO_MODEL = "fal-ai/stable-audio-25/text-to-audio";
|
||||
const DEFAULT_TIMEOUT_MS = 180_000;
|
||||
const DEFAULT_GENERATED_MUSIC_MAX_BYTES = 16 * 1024 * 1024;
|
||||
|
||||
const FAL_MUSIC_MODELS = [
|
||||
DEFAULT_FAL_MUSIC_MODEL,
|
||||
FAL_ACE_STEP_MODEL,
|
||||
FAL_STABLE_AUDIO_MODEL,
|
||||
] as const;
|
||||
|
||||
function resolveFalMusicModel(model: string | undefined): string {
|
||||
return normalizeOptionalString(model) ?? DEFAULT_FAL_MUSIC_MODEL;
|
||||
}
|
||||
|
||||
function resolveGeneratedMusicMaxBytes(req: MusicGenerationRequest): number {
|
||||
const configured = req.cfg.agents?.defaults?.mediaMaxMb;
|
||||
if (typeof configured === "number" && Number.isFinite(configured) && configured > 0) {
|
||||
return Math.floor(configured * 1024 * 1024);
|
||||
}
|
||||
return DEFAULT_GENERATED_MUSIC_MAX_BYTES;
|
||||
}
|
||||
|
||||
function buildFalMinimaxBody(req: MusicGenerationRequest): Record<string, unknown> {
|
||||
const lyrics = normalizeOptionalString(req.lyrics);
|
||||
if (lyrics && req.instrumental === true) {
|
||||
throw new Error("fal MiniMax music generation cannot use lyrics when instrumental=true.");
|
||||
}
|
||||
return {
|
||||
prompt: req.prompt,
|
||||
...(lyrics ? { lyrics } : {}),
|
||||
...(req.instrumental === true ? { is_instrumental: true } : {}),
|
||||
...(!lyrics && req.instrumental !== true ? { lyrics_optimizer: true } : {}),
|
||||
...(typeof req.durationSeconds === "number" ? { duration: req.durationSeconds } : {}),
|
||||
audio_setting: {
|
||||
sample_rate: 44_100,
|
||||
bitrate: 256_000,
|
||||
format: req.format ?? "mp3",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function buildFalAceStepBody(req: MusicGenerationRequest): Record<string, unknown> {
|
||||
if (normalizeOptionalString(req.lyrics)) {
|
||||
throw new Error("fal ACE-Step music generation does not support explicit lyrics.");
|
||||
}
|
||||
return {
|
||||
prompt: req.prompt,
|
||||
...(req.instrumental === true ? { instrumental: true } : {}),
|
||||
...(typeof req.durationSeconds === "number" ? { duration: req.durationSeconds } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
function buildFalStableAudioBody(req: MusicGenerationRequest): Record<string, unknown> {
|
||||
if (normalizeOptionalString(req.lyrics)) {
|
||||
throw new Error("fal Stable Audio music generation does not support explicit lyrics.");
|
||||
}
|
||||
if (req.instrumental === true) {
|
||||
throw new Error("fal Stable Audio music generation does not support instrumental mode.");
|
||||
}
|
||||
return {
|
||||
prompt: req.prompt,
|
||||
...(typeof req.durationSeconds === "number" ? { seconds_total: req.durationSeconds } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
function buildFalMusicRequestBody(
|
||||
req: MusicGenerationRequest,
|
||||
model: string,
|
||||
): Record<string, unknown> {
|
||||
if (model === FAL_ACE_STEP_MODEL) {
|
||||
return buildFalAceStepBody(req);
|
||||
}
|
||||
if (model === FAL_STABLE_AUDIO_MODEL) {
|
||||
return buildFalStableAudioBody(req);
|
||||
}
|
||||
return buildFalMinimaxBody(req);
|
||||
}
|
||||
|
||||
function resolveFalMusicMetadata(payload: unknown): Record<string, unknown> | undefined {
|
||||
if (!payload || typeof payload !== "object" || Array.isArray(payload)) {
|
||||
return undefined;
|
||||
}
|
||||
const metadata: Record<string, unknown> = {};
|
||||
for (const key of ["seed", "tags"]) {
|
||||
const value = (payload as Record<string, unknown>)[key];
|
||||
if (value !== undefined && value !== null) {
|
||||
metadata[key] = value;
|
||||
}
|
||||
}
|
||||
return Object.keys(metadata).length > 0 ? metadata : undefined;
|
||||
}
|
||||
|
||||
export function buildFalMusicGenerationProvider(): MusicGenerationProvider {
|
||||
return {
|
||||
id: "fal",
|
||||
label: "fal",
|
||||
defaultModel: DEFAULT_FAL_MUSIC_MODEL,
|
||||
models: [...FAL_MUSIC_MODELS],
|
||||
isConfigured: ({ agentDir }) =>
|
||||
isProviderApiKeyConfigured({
|
||||
provider: "fal",
|
||||
agentDir,
|
||||
}),
|
||||
capabilities: {
|
||||
generate: {
|
||||
maxTracks: 1,
|
||||
maxDurationSeconds: 240,
|
||||
supportsLyrics: true,
|
||||
supportsLyricsByModel: {
|
||||
[FAL_ACE_STEP_MODEL]: false,
|
||||
[FAL_STABLE_AUDIO_MODEL]: false,
|
||||
},
|
||||
supportsInstrumental: true,
|
||||
supportsInstrumentalByModel: {
|
||||
[FAL_STABLE_AUDIO_MODEL]: false,
|
||||
},
|
||||
supportsDuration: true,
|
||||
supportsFormat: true,
|
||||
supportedFormats: ["mp3", "wav"],
|
||||
supportedFormatsByModel: {
|
||||
[DEFAULT_FAL_MUSIC_MODEL]: ["mp3"],
|
||||
[FAL_ACE_STEP_MODEL]: ["wav"],
|
||||
[FAL_STABLE_AUDIO_MODEL]: ["wav"],
|
||||
},
|
||||
},
|
||||
edit: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
async generateMusic(req) {
|
||||
if ((req.inputImages?.length ?? 0) > 0) {
|
||||
throw new Error("fal music generation does not support image reference inputs.");
|
||||
}
|
||||
|
||||
const { baseUrl, allowPrivateNetwork, headers, dispatcherPolicy } =
|
||||
await resolveFalHttpRequestConfig({ req, capability: "audio" });
|
||||
const model = resolveFalMusicModel(req.model);
|
||||
const { response, release } = await postJsonRequest({
|
||||
url: `${baseUrl}/${model}`,
|
||||
headers,
|
||||
body: buildFalMusicRequestBody(req, model),
|
||||
timeoutMs: req.timeoutMs ?? DEFAULT_TIMEOUT_MS,
|
||||
fetchFn: fetch,
|
||||
allowPrivateNetwork,
|
||||
dispatcherPolicy,
|
||||
});
|
||||
|
||||
try {
|
||||
await assertOkOrThrowHttpError(response, "fal music generation failed");
|
||||
const payload = await readProviderJsonResponse<unknown>(response, "fal music generation");
|
||||
const [candidate] = extractGeneratedMusicFileCandidates(payload);
|
||||
if (!candidate) {
|
||||
throw new Error("fal music generation response missing audio output");
|
||||
}
|
||||
const track = await downloadGeneratedMusicAsset({
|
||||
candidate,
|
||||
timeoutMs: req.timeoutMs ?? DEFAULT_TIMEOUT_MS,
|
||||
fetchFn: fetch,
|
||||
provider: "fal",
|
||||
requestFailedMessage: "fal generated music download failed",
|
||||
maxBytes: resolveGeneratedMusicMaxBytes(req),
|
||||
});
|
||||
const lyrics =
|
||||
typeof payload === "object" && payload && !Array.isArray(payload)
|
||||
? normalizeOptionalString((payload as Record<string, unknown>).lyrics)
|
||||
: undefined;
|
||||
return {
|
||||
tracks: [track],
|
||||
model,
|
||||
...(lyrics ? { lyrics: [lyrics] } : {}),
|
||||
metadata: {
|
||||
...resolveFalMusicMetadata(payload),
|
||||
...(track.metadata?.url ? { audioUrl: track.metadata.url } : {}),
|
||||
instrumental: req.instrumental === true,
|
||||
...(req.format ? { requestedFormat: req.format } : {}),
|
||||
...(typeof req.durationSeconds === "number"
|
||||
? { requestedDurationSeconds: req.durationSeconds }
|
||||
: {}),
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
await release();
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user