Fix composer hangs and JSON failures (no timeout on the LLM call)

#2
by multimodalart HF Staff - opened
Files changed (1) hide show
  1. app.py +21 -9
app.py CHANGED
@@ -501,15 +501,27 @@ def _llm_json(system, user):
501
 
502
  from openai import OpenAI
503
 
504
- client = OpenAI(base_url="https://router.huggingface.co/v1", api_key=os.environ["HF_TOKEN"])
505
- completion = client.chat.completions.create(
506
- model="MiniMaxAI/MiniMax-M3:fastest",
507
- messages=[{"role": "system", "content": system}, {"role": "user", "content": user}],
508
- )
509
- text = completion.choices[0].message.content.strip()
510
- if text.startswith("```"):
511
- text = text.split("```")[1].removeprefix("json").strip()
512
- return _json.loads(text)
 
 
 
 
 
 
 
 
 
 
 
 
513
 
514
 
515
  def compose_song(description, duration):
 
501
 
502
  from openai import OpenAI
503
 
504
+ # Bounded timeout: a hung provider must fail over, not freeze the UI at the composing step.
505
+ client = OpenAI(base_url="https://router.huggingface.co/v1", api_key=os.environ["HF_TOKEN"], timeout=60, max_retries=0)
506
+ last_error = None
507
+ for model in ("MiniMaxAI/MiniMax-M3:fastest", "MiniMaxAI/MiniMax-M3", "MiniMaxAI/MiniMax-M3:fireworks-ai"):
508
+ try:
509
+ completion = client.chat.completions.create(
510
+ model=model,
511
+ messages=[{"role": "system", "content": system}, {"role": "user", "content": user}],
512
+ )
513
+ text = completion.choices[0].message.content or ""
514
+ # Tolerate fences/preambles and reject truncated replies: parse the outermost {...} span.
515
+ start, end = text.find("{"), text.rfind("}")
516
+ if start == -1 or end <= start:
517
+ raise ValueError(f"no JSON object in composer reply (finish_reason={completion.choices[0].finish_reason})")
518
+ return _json.loads(text[start : end + 1])
519
+ except Exception as e:
520
+ last_error = e
521
+ raise gr.Error(
522
+ "The MiniMax-M3 composer is overloaded right now — try again in a moment, "
523
+ "or write the lyrics and structured prompt directly in the Studio tab."
524
+ ) from last_error
525
 
526
 
527
  def compose_song(description, duration):