feat: Maestro Mode - context-aware prompt generation

- Backend: POST /api/text-gen/maestro endpoint with dual modes
  - Empty prompt → generate from scratch (temp 1.0)
  - Non-empty prompt → complete/extend (temp 0.85)
  - structured=true → returns JSON fields for Advanced/Pro mode
  - Three system prompts: MAESTRO_GENERATE, MAESTRO_COMPLETE, MAESTRO_STRUCTURED
  - Trailing sentence cleanup for plain text mode
  - JSON fallback parsing for structured mode

- Frontend: MaestroButton component
  - Context-aware labels: ♪ Maestro Mode (empty) / ♪ Keep Composing (has content)
  - Loading states: animating ♩ with Dreaming.../Composing...
  - structured prop for Pro mode → populates structured fields
  - onStructuredResult callback merges fields into StructuredPrompt

- UX: Replaced 'Get Suggestions ✨' with Maestro Mode
  - Suggestions required text in the box; Maestro works with or without
  - Single button, context-aware behavior, cleaner UI
  - Advanced/Pro mode gets structured fields from Maestro
  - Removed SuggestionsModal dependency

- Rename: 'Compose for Me' → 'Keep Composing'
This commit is contained in:
rin.kagamine committed 2026-05-31 10:13:43 -04:00
1 parent 816f8fbd2f
commit e0ce9e4b6c
4 files changed
+304 -33

No files matched your search

+21 -1
View File
@@ -15,7 +15,7 @@ from kithara_client import generate_clip, save_clip_file
from waveform import generate_waveform_svg, get_waveform_path
from analysis import analyze_clip
from image_gen import generate_artwork, get_image_gen_config, get_available_models, SAFETY_LEVELS
from text_gen import suggest_prompts, get_text_gen_config, get_available_models as get_text_models
from text_gen import suggest_prompts, maestro_prompt, get_text_gen_config, get_available_models as get_text_models
app = FastAPI(title="Kithara Studio", version="0.1.0")
@@ -447,6 +447,26 @@ async def get_suggestions(request: dict):
except Exception as e:
raise HTTPException(status_code=500, detail=f"Suggestion generation failed: {str(e)}")
@app.post("/api/text-gen/maestro")
async def maestro(request: dict):
"""Generate or complete a music prompt using Maestro Mode.
If hint is empty/missing: generates a creative prompt from scratch ("Dream for Me").
If hint is provided: completes the user's existing prompt ("Keep Composing").
If structured=true: returns JSON fields for Advanced/Pro mode instead of plain text.
"""
hint = request.get("hint", "").strip()
model = request.get("model") # Optional text model override
structured = request.get("structured", False) # Return structured fields for Pro mode
try:
config = get_text_gen_config()
result = await maestro_prompt(hint=hint, model=model, config=config, structured=structured)
return result
except Exception as e:
raise HTTPException(status_code=500, detail=f"Maestro generation failed: {str(e)}")
@app.patch("/api/clips/{clip_id}")
async def rename_clip_endpoint(clip_id: str, request: RenameRequest):
clip = await get_clip(clip_id)