GitHub radar: self-healing by regeneration ¶
The
examples/github_radar/
package watches a GitHub project's releases page and answers a question every
scraper eventually faces: what happens when the site changes and your
deterministic script breaks?
The Conatus answer is regeneration. A compiled recipe runs deterministically and free — until the site changes and it breaks. Then, instead of a human babysitting it, the agent is automatically re-triggered to re-author the recipe, and you are back to deterministic execution:
How it works ¶
gh.py mirrors the EDGAR example: typed actions
(fetch_releases_page, extract_releases) that return a non-serializable
HTML page and typed Release records, passed between steps by reference.
self_heal_regenerate.py stages the failure. stale_recipe plays the part of a
recipe the agent authored months ago, before GitHub renamed the release
container — its CSS selector now matches nothing. A small wrapper runs the
recipe first, checks the output against a contract, and falls back to the agent
task only when the recipe misbehaves:
def run_or_regenerate(recipe, agent_task, *args, ok):
"""Run the deterministic recipe; if it misbehaves, regenerate."""
try:
result = recipe(*args)
except Exception as why:
print(f" ! recipe failed: {why}")
else:
if ok(result):
return result, "deterministic recipe (free, no model)"
print(f" ! recipe output failed its contract: {result!r}")
print(" -> re-triggering the agent to re-author the recipe...")
return agent_task.run(*args), "REGENERATED by the agent"
The fallback is an ordinary task built from the same typed actions:
@task(actions=[fetch_releases_page, extract_releases])
def recent_releases(repo: str) -> list[Release]:
"""List a GitHub project's recent releases."""
Because the agent re-derives the result from the live page, the regenerated run also produces a fresh recipe — so the next execution is deterministic and free again. The model only gets involved when the world changes.
Run it ¶
Needs an OPENAI_API_KEY (the stale recipe fails by design, so the agent path
runs):
Source:
examples/github_radar/