| 25 | |
| 26 | |
| 27 | def extract_submodule_result_value(value: Any) -> Optional[str]: |
| 28 | def _extract_from_text(text: str) -> Optional[str]: |
| 29 | if not text: |
| 30 | return None |
| 31 | lines = text.splitlines() |
| 32 | for idx, line in enumerate(lines): |
| 33 | stripped = line.strip() |
| 34 | if not stripped: |
| 35 | continue |
| 36 | if not stripped.startswith("RETURN:"): |
| 37 | return None |
| 38 | first_payload = stripped.split("RETURN:", 1)[1].strip() |
| 39 | rest_lines = [] |
| 40 | for rest in lines[idx + 1 :]: |
| 41 | rest_stripped = rest.strip() |
| 42 | if rest_stripped.startswith("RETURN:"): |
| 43 | rest_lines.append(rest_stripped.split("RETURN:", 1)[1].strip()) |
| 44 | else: |
| 45 | rest_lines.append(rest) |
| 46 | if rest_lines: |
| 47 | return "\n".join([first_payload] + rest_lines) |
| 48 | return first_payload |
| 49 | return None |
| 50 | |
| 51 | if value is None: |
| 52 | return None |
| 53 | if isinstance(value, dict): |
| 54 | for key in ("output", "content", "result", "stdout"): |
| 55 | if key in value and isinstance(value[key], str): |
| 56 | extracted = _extract_from_text(value[key]) |
| 57 | if extracted is not None: |
| 58 | return extracted |
| 59 | if isinstance(value, str): |
| 60 | return _extract_from_text(value) |
| 61 | try: |
| 62 | serialized = json.dumps(value, default=str) |
| 63 | except Exception: |
| 64 | serialized = str(value) |
| 65 | return _extract_from_text(serialized) |