Spaces:
Sleeping
Sleeping
| """Apply HermesFace patches to upstream ``agent/auxiliary_client.py``.""" | |
| from __future__ import annotations | |
| from pathlib import Path | |
| from sync_hf import _replace_exact_once, _replace_required_once | |
| _PATCH_MARKER = "# HermesFace: configured fallback respects unhealthy cache" | |
| def _patch_payment_fallback_block( | |
| code: str, | |
| *, | |
| log_prefix: str, | |
| label: str, | |
| ) -> tuple[str, bool]: | |
| old = ( | |
| f"{log_prefix}\n" | |
| " task or \"call\", reason, resolved_provider, first_err)\n" | |
| "\n" | |
| " # Fallback order (#26882, #26803):\n" | |
| " # 1. User-configured fallback_chain (per-task) if set\n" | |
| " # 2. For auto: top-level main fallback_providers/fallback_model\n" | |
| " # 3. For auto: built-in auxiliary discovery chain\n" | |
| " # 4. For explicit aux providers: main agent model safety net\n" | |
| " fb_client, fb_model, fb_label = (None, None, \"\")\n" | |
| " if is_auto:\n" | |
| " fb_client, fb_model, fb_label = _try_configured_fallback_chain(\n" | |
| " task, resolved_provider or \"auto\", reason=reason)\n" | |
| " if fb_client is None:\n" | |
| " fb_client, fb_model, fb_label = _try_main_fallback_chain(\n" | |
| " task, resolved_provider or \"auto\", reason=reason)\n" | |
| " if fb_client is None:\n" | |
| " fb_client, fb_model, fb_label = _try_payment_fallback(\n" | |
| " resolved_provider, task, reason=reason)\n" | |
| " else:\n" | |
| " fb_client, fb_model, fb_label = _try_configured_fallback_chain(\n" | |
| " task, resolved_provider or \"auto\", reason=reason)\n" | |
| ) | |
| new = ( | |
| f"{log_prefix}\n" | |
| " task or \"call\", reason, resolved_provider, first_err)\n" | |
| "\n" | |
| " # Fallback order (#26882, #26803):\n" | |
| " # 1. User-configured fallback_chain (per-task) if set\n" | |
| " # 2. For auto: top-level main fallback_providers/fallback_model\n" | |
| " # 3. For auto: built-in auxiliary discovery chain\n" | |
| " # 4. For explicit aux providers: main agent model safety net\n" | |
| " fb_client, fb_model, fb_label = (None, None, \"\")\n" | |
| " _failed_chain_provider = (\n" | |
| " _recoverable_pool_provider(resolved_provider, client, main_runtime=main_runtime)\n" | |
| " or resolved_provider\n" | |
| " or \"auto\"\n" | |
| " )\n" | |
| " if is_auto:\n" | |
| " fb_client, fb_model, fb_label = _try_configured_fallback_chain(\n" | |
| " task, _failed_chain_provider, reason=reason)\n" | |
| " if fb_client is None:\n" | |
| " fb_client, fb_model, fb_label = _try_main_fallback_chain(\n" | |
| " task, _failed_chain_provider, reason=reason)\n" | |
| " if fb_client is None:\n" | |
| " fb_client, fb_model, fb_label = _try_payment_fallback(\n" | |
| " resolved_provider, task, reason=reason)\n" | |
| " else:\n" | |
| " fb_client, fb_model, fb_label = _try_configured_fallback_chain(\n" | |
| " task, _failed_chain_provider, reason=reason)\n" | |
| ) | |
| return _replace_exact_once(code, old, new, label=label) | |
| def apply_auxiliary_client_fallback_patch(aux_path: Path) -> list[str]: | |
| """Patch fallback selection to honor unhealthy providers and concrete failures.""" | |
| if not aux_path.is_file(): | |
| raise RuntimeError(f"required upstream auxiliary client missing: {aux_path}") | |
| code = aux_path.read_text(encoding="utf-8") | |
| if _PATCH_MARKER in code: | |
| return ["auxiliary_client fallback patch already applied"] | |
| changes: list[str] = [] | |
| unhealthy_block = ( | |
| ' label = f"fallback_chain[{i}]({fb_provider})"\n\n' | |
| " try:\n" | |
| ) | |
| unhealthy_replacement = ( | |
| ' label = f"fallback_chain[{i}]({fb_provider})"\n' | |
| f" {_PATCH_MARKER}\n" | |
| " fb_norm = fb_provider.lower()\n" | |
| " if _is_provider_unhealthy(fb_norm):\n" | |
| " _log_skip_unhealthy(fb_norm, task)\n" | |
| ' tried.append(f"{label} (unhealthy)")\n' | |
| " continue\n\n" | |
| " try:\n" | |
| ) | |
| code = _replace_required_once( | |
| code, | |
| unhealthy_block, | |
| unhealthy_replacement, | |
| label="auxiliary configured fallback unhealthy skip", | |
| ) | |
| changes.append("configured fallback_chain skips unhealthy providers") | |
| code, changed = _patch_payment_fallback_block( | |
| code, | |
| log_prefix=' logger.info("Auxiliary %s: %s on %s (%s), trying fallback",', | |
| label="auxiliary sync payment fallback failed-provider label", | |
| ) | |
| if changed: | |
| changes.append("sync payment fallback passes concrete failed provider") | |
| code, changed = _patch_payment_fallback_block( | |
| code, | |
| log_prefix=' logger.info("Auxiliary %s (async): %s on %s (%s), trying fallback",', | |
| label="auxiliary async payment fallback failed-provider label", | |
| ) | |
| if changed: | |
| changes.append("async payment fallback passes concrete failed provider") | |
| openrouter_guard_old = ( | |
| ' or_key = explicit_api_key or os.getenv("OPENROUTER_API_KEY")\n' | |
| " if not or_key:\n" | |
| ) | |
| openrouter_guard_new = ( | |
| ' or_key = explicit_api_key or os.getenv("OPENROUTER_API_KEY")\n' | |
| " chosen_model = model or _OPENROUTER_MODEL\n" | |
| ' if chosen_model and ":free" not in str(chosen_model).lower():\n' | |
| " logger.error(\n" | |
| ' "Auxiliary OpenRouter call refused: model %r lacks :free suffix "\n' | |
| ' "(set OPENROUTER_ANALYSIS_MODEL to a :free model)",\n' | |
| " chosen_model,\n" | |
| " )\n" | |
| " return None, None\n" | |
| " if not or_key:\n" | |
| ) | |
| code = _replace_required_once( | |
| code, | |
| openrouter_guard_old, | |
| openrouter_guard_new, | |
| label="auxiliary OpenRouter :free guard", | |
| ) | |
| changes.append("OpenRouter auxiliary calls require :free model suffix") | |
| resolve_openrouter_old = ( | |
| " if provider == \"openrouter\":\n" | |
| " client, default = _try_openrouter(explicit_api_key=explicit_api_key)\n" | |
| ) | |
| resolve_openrouter_new = ( | |
| " if provider == \"openrouter\":\n" | |
| " chosen_model = model or _OPENROUTER_MODEL\n" | |
| ' if chosen_model and ":free" not in str(chosen_model).lower():\n' | |
| " logger.error(\n" | |
| ' "resolve_provider_client: refusing paid OpenRouter model %r "\n' | |
| ' "(model id must include :free)",\n' | |
| " chosen_model,\n" | |
| " )\n" | |
| " return None, None\n" | |
| " client, default = _try_openrouter(explicit_api_key=explicit_api_key, model=model)\n" | |
| ) | |
| code = _replace_required_once( | |
| code, | |
| resolve_openrouter_old, | |
| resolve_openrouter_new, | |
| label="resolve_provider_client OpenRouter :free guard", | |
| ) | |
| changes.append("resolve_provider_client refuses paid OpenRouter models") | |
| aux_path.write_text(code, encoding="utf-8") | |
| return changes | |