@@ -244,13 +244,34 @@ def parse_response(s: str) -> dict:
244244 s = s .strip ()
245245 s = re .sub (r"^```(?:json)?\s*" , "" , s , flags = re .I )
246246 s = re .sub (r"\s*```$" , "" , s )
247- # Some CLIs prefix a status line; try to locate the first { and last }.
248- if not s .startswith ("{" ):
249- start = s .find ("{" )
250- end = s .rfind ("}" )
251- if start != - 1 and end != - 1 :
252- s = s [start : end + 1 ]
253- return json .loads (s )
247+ # The model sometimes emits scratchpad objects (e.g. {"intent": "..."})
248+ # before the real decision object. Walk all top-level JSON objects in
249+ # the string and return the last one that has a "decision" key, falling
250+ # back to the last object if none match.
251+ decoder = json .JSONDecoder ()
252+ objects : list [dict ] = []
253+ i = 0
254+ n = len (s )
255+ while i < n :
256+ # Skip to the next object start.
257+ j = s .find ("{" , i )
258+ if j == - 1 :
259+ break
260+ try :
261+ obj , end = decoder .raw_decode (s , j )
262+ except json .JSONDecodeError :
263+ i = j + 1
264+ continue
265+ if isinstance (obj , dict ):
266+ objects .append (obj )
267+ i = end
268+ if not objects :
269+ # Force the original error path for callers that expect JSONDecodeError.
270+ return json .loads (s )
271+ for obj in reversed (objects ):
272+ if "decision" in obj :
273+ return obj
274+ return objects [- 1 ]
254275
255276
256277def validate (decision : dict ) -> list [str ]:
@@ -356,7 +377,7 @@ def process_one(bundle: PrBundle, args) -> tuple[str, str | None, dict | None]:
356377def main () -> int :
357378 ap = argparse .ArgumentParser (description = __doc__ , formatter_class = argparse .RawDescriptionHelpFormatter )
358379 ap .add_argument ("--jobs" , type = int , default = 4 , help = "parallel CLI invocations (default 4)" )
359- ap .add_argument ("--timeout" , type = int , default = 300 , help = "per-PR CLI timeout seconds" )
380+ ap .add_argument ("--timeout" , type = int , default = 900 , help = "per-PR CLI timeout seconds" )
360381 ap .add_argument ("--force" , action = "store_true" , help = "re-classify PRs with existing decision.json" )
361382 ap .add_argument ("--only" , type = int , nargs = "*" , help = "restrict to these PR numbers" )
362383 ap .add_argument (
0 commit comments