From fb140966275c7388df31daf36805541f06a3b609 Mon Sep 17 00:00:00 2001 From: Concedo <39025047+LostRuins@users.noreply.github.com> Date: Fri, 18 Sep 2026 00:15:44 +0800 Subject: [PATCH] allow music llm mode to gen audio codes --- embd_res/kcpp_musicui.embd | 33 +++++++++++++++++++++++++++++++-- koboldcpp.py | 5 +++-- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/embd_res/kcpp_musicui.embd b/embd_res/kcpp_musicui.embd index 66b426355..c78fcf329 100644 --- a/embd_res/kcpp_musicui.embd +++ b/embd_res/kcpp_musicui.embd @@ -424,12 +424,14 @@ async function fetchVoices(){ } var has_llm_loaded = false; +var has_music_llm_loaded = false; let statsRequestId = 0; let plannerSelectionVersion = 0; async function fetchStats(){ const requestId = ++statsRequestId; const selectionVersion = plannerSelectionVersion; has_llm_loaded = false; + has_music_llm_loaded = false; document.getElementById("planner").value = "music_lm"; updatePlannerOptions(); try{ @@ -451,10 +453,11 @@ async function fetchStats(){ const perf = await res.json(); if(requestId !== statsRequestId) return; has_llm_loaded = !!(perf && perf.llm); + has_music_llm_loaded = !!(perf && perf.musicllm); if(selectionVersion === plannerSelectionVersion){ document.getElementById("planner").value = has_llm_loaded ? "main_llm" : "music_lm"; - updatePlannerOptions(); } + updatePlannerOptions(); }catch(e){ @@ -660,7 +663,7 @@ function deriveTitle(caption){ function updatePlannerOptions(){ const useLLM = document.getElementById("planner").value === "main_llm"; - document.getElementById("gen_codes_option").classList.toggle("hidden", useLLM); + document.getElementById("gen_codes_option").classList.toggle("hidden", useLLM && !has_music_llm_loaded); } async function planSong() @@ -735,6 +738,9 @@ async function planSongWithLLM(){ } let origPayload = getFormData(); + const generateCodes = origPayload.gen_codes && has_music_llm_loaded; + const planningController = currentController; + const codesUrl = buildUrl("/api/extra/music/prepare"); const songDetails = {caption: origPayload.caption || "an interesting song"}; ["lyrics", "bpm", "duration", "keyscale", "timesignature", "vocal_language"].forEach(key=>{ if(origPayload[key] !== undefined) songDetails[key] = origPayload[key]; @@ -768,6 +774,29 @@ async function planSongWithLLM(){ delete toolres.caption; } updateForm(toolres); + if(generateCodes){ + document.getElementById("audio_codes").value = ""; + showMessage("Song details ready. Generating audio codes..."); + const codesPayload = {...origPayload, ...toolres, gen_codes:true, rewrite_caption:false, audio_codes:""}; + try{ + const codesRes = await fetch(codesUrl, { + method:"POST", + headers:headers, + body:JSON.stringify(codesPayload), + signal:planningController.signal + }); + if(!codesRes.ok) throw new Error(`HTTP ${codesRes.status}`); + const codesData = await codesRes.json(); + if(codesData.error) throw new Error(codesData.error); + if(typeof codesData.audio_codes !== "string" || !codesData.audio_codes.trim()){ + throw new Error("Music planner returned no audio codes."); + } + document.getElementById("audio_codes").value = codesData.audio_codes; + }catch(e){ + if(e.name !== "AbortError") showMessage(`Song details saved, but audio code generation failed: ${e.message}`); + return; + } + } showMessage("Plan generated."); }catch(e){ console.error(e); diff --git a/koboldcpp.py b/koboldcpp.py index 6744e9ab6..6837f617e 100644 --- a/koboldcpp.py +++ b/koboldcpp.py @@ -1532,7 +1532,7 @@ def get_capabilities(): has_mcp = True if (args.mcpfile and mcp_connections and len(mcp_connections) > 0) else False admin_type = (2 if args.admin and args.admindir and args.adminpassword else (1 if args.admin and args.admindir else 0)) has_router = True if args.routermode else False - return {"result":"KoboldCpp", "version":KcppVersion, "protected":has_password, "llm":has_llm, "txt2img":has_txt2img,"vision":visionSupport,"audio":audioSupport,"transcribe":has_whisper,"multiplayer":has_multiplayer,"websearch":has_search,"tts":has_tts, "embeddings":has_embeddings, "music":has_music, "savedata":(savedata_obj is not None), "admin": admin_type, "router":has_router, "guidance": has_guidance, "jinja": has_jinja, "mcp":has_mcp} + return {"result":"KoboldCpp", "version":KcppVersion, "protected":has_password, "llm":has_llm, "txt2img":has_txt2img,"vision":visionSupport,"audio":audioSupport,"transcribe":has_whisper,"multiplayer":has_multiplayer,"websearch":has_search,"tts":has_tts, "embeddings":has_embeddings, "music":has_music, "musicllm":bool(musicllmmodelpath), "savedata":(savedata_obj is not None), "admin": admin_type, "router":has_router, "guidance": has_guidance, "jinja": has_jinja, "mcp":has_mcp} def scan_directory(dirpath, valid_exts, depth): @@ -3400,7 +3400,7 @@ def embeddings_generate(genparams): return {"count":tokcnt, "data":tokarrs} def music_load_model(musicllm,musicembedding,musicdiffusion,musicvae): - global args + global args, musicllmmodelpath inputs = music_load_model_inputs() inputs.musicllm_filename = musicllm.encode("UTF-8") inputs.musicembedding_filename = musicembedding.encode("UTF-8") @@ -3409,6 +3409,7 @@ def music_load_model(musicllm,musicembedding,musicdiffusion,musicvae): inputs.lowvram = True if args.musiclowvram else False inputs = set_backend_props(inputs) ret = handle.music_load_model(inputs) + musicllmmodelpath = musicllm if ret else "" return ret def music_generate_codes(genparams):