Self-refining inference: draft → critique → refine loop. Wraps core/inference_v2.infer() without changing the agent's message history or tool-call protocol. The refined response is returned in place of the plain infer() response. Args: messages: Full message l
(
messages: list,
task_type: str = "code",
user_message: str = "",
max_depth: int = None,
quality_threshold: float = None,
extra_stop: list = None,
stream: bool = True,
)
| 242 | # ── Main API ────────────────────────────────────────────────────────────────── |
| 243 | |
| 244 | def recursive_infer( |
| 245 | messages: list, |
| 246 | task_type: str = "code", |
| 247 | user_message: str = "", |
| 248 | max_depth: int = None, |
| 249 | quality_threshold: float = None, |
| 250 | extra_stop: list = None, |
| 251 | stream: bool = True, |
| 252 | ) -> str: |
| 253 | """ |
| 254 | Self-refining inference: draft → critique → refine loop. |
| 255 | |
| 256 | Wraps core/inference_v2.infer() without changing the agent's message history |
| 257 | or tool-call protocol. The refined response is returned in place of the |
| 258 | plain infer() response. |
| 259 | |
| 260 | Args: |
| 261 | messages: Full message list (system + history + user message) |
| 262 | task_type: "code" | "write_file" | "patch_file" | "plan" | "tool" |
| 263 | user_message: Original user message text (for KB retrieval queries) |
| 264 | max_depth: Max critique+refine cycles (default from RECURSIVE_CONFIG) |
| 265 | quality_threshold: 0–1 gate; above this the draft is accepted (default 0.7) |
| 266 | extra_stop: Additional stop tokens forwarded to infer() |
| 267 | stream: Whether to stream final output tokens (default True) |
| 268 | |
| 269 | Returns: |
| 270 | Final (possibly refined) response string. Never raises — errors are returned |
| 271 | as "[ERROR] ..." strings matching the normal infer() contract. |
| 272 | """ |
| 273 | # Guard: return immediately if recursive inference is disabled |
| 274 | if not RECURSIVE_CONFIG.get("enabled", True): |
| 275 | from core.inference_v2 import infer |
| 276 | return infer(messages, stream=stream, |
| 277 | extra_stop=extra_stop or ["</tool>"], show_thinking=True) |
| 278 | |
| 279 | cfg = RECURSIVE_CONFIG |
| 280 | if max_depth is None: |
| 281 | max_depth = cfg.get("max_depth", 1) |
| 282 | if quality_threshold is None: |
| 283 | quality_threshold = cfg.get("quality_threshold", 0.7) |
| 284 | if extra_stop is None: |
| 285 | extra_stop = ["</tool>"] |
| 286 | |
| 287 | # Phase 8: Adapt depth to thermal/battery state |
| 288 | max_depth = get_adaptive_depth(max_depth) |
| 289 | |
| 290 | # ── Step 1: Generate initial draft ──────────────────────────────────────── |
| 291 | try: |
| 292 | from core.inference_v2 import infer |
| 293 | except Exception as e: |
| 294 | return f"[ERROR] recursive_infer: cannot import infer: {e}" |
| 295 | |
| 296 | try: |
| 297 | _log_phase("Draft", 1, max_depth + 1) |
| 298 | draft = infer(messages, stream=stream, |
| 299 | extra_stop=extra_stop, show_thinking=True) |
| 300 | except Exception as e: |
| 301 | return f"[ERROR] recursive_infer draft: {e}" |
no test coverage detected