| 105 | |
| 106 | |
| 107 | def parse_json_output(raw: str, *, action_field: str = "bash_command") -> dict[str, Any]: |
| 108 | try: |
| 109 | parsed = json.loads(raw) |
| 110 | except json.JSONDecodeError as exc: |
| 111 | raise ValueError(f"Unable to parse JSON output: {exc}") from exc |
| 112 | if not isinstance(parsed, dict): |
| 113 | raise ValueError("Model output was JSON but not a JSON object.") |
| 114 | # Strict-schema responses cannot have done=true with a non-empty action; |
| 115 | # tolerate it from non-strict callers by demoting `done`. |
| 116 | action_text = str(parsed.get(action_field, "") or "").strip() |
| 117 | if action_text and bool(parsed.get("done", False)): |
| 118 | parsed = dict(parsed) |
| 119 | parsed["done"] = False |
| 120 | return parsed |
| 121 | |
| 122 | |
| 123 | def _validate_bash_command(command: str) -> None: |