yonagush Claude Sonnet 4.6 commited on
Commit
6d4d2b0
·
1 Parent(s): 0050680

fix: force JSON output from Groq to prevent JSONDecodeError

Browse files

Add response_format={"type":"json_object"} to Groq API call so the
model always returns structurally valid JSON. Add a regex fallback
extractor as a second safety net for any edge cases.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Files changed (1) hide show
  1. services/story_service.py +13 -3
services/story_service.py CHANGED
@@ -97,16 +97,26 @@ async def generate_episode(
97
  {"role": "user", "content": prompt},
98
  ],
99
  temperature=0.92,
100
- max_tokens=4000, # 20 scenes need more tokens
 
101
  )
102
 
103
  raw = resp.choices[0].message.content.strip()
104
 
105
- # Strip markdown fences if model added them
106
  raw = re.sub(r"^```(?:json)?\s*", "", raw, flags=re.MULTILINE)
107
  raw = re.sub(r"\s*```$", "", raw, flags=re.MULTILINE)
108
 
109
- data = json.loads(raw)
 
 
 
 
 
 
 
 
 
110
 
111
  # Sanitize text — strip markdown bold/italic/etc
112
  def clean(s: str) -> str:
 
97
  {"role": "user", "content": prompt},
98
  ],
99
  temperature=0.92,
100
+ max_tokens=4000,
101
+ response_format={"type": "json_object"},
102
  )
103
 
104
  raw = resp.choices[0].message.content.strip()
105
 
106
+ # Strip markdown fences if model added them anyway
107
  raw = re.sub(r"^```(?:json)?\s*", "", raw, flags=re.MULTILINE)
108
  raw = re.sub(r"\s*```$", "", raw, flags=re.MULTILINE)
109
 
110
+ # Try parsing; if it fails extract the outermost JSON object as a fallback
111
+ try:
112
+ data = json.loads(raw)
113
+ except json.JSONDecodeError:
114
+ # Find the first { ... } blob and try again
115
+ m = re.search(r"\{.*\}", raw, re.DOTALL)
116
+ if m:
117
+ data = json.loads(m.group(0))
118
+ else:
119
+ raise
120
 
121
  # Sanitize text — strip markdown bold/italic/etc
122
  def clean(s: str) -> str: