The agent loop checked signal.aborted only at the top of each iteration, but the LLM fetch() call (which takes seconds) never received the signal. Now the signal is passed to fetch() and checked after LLM errors and before the inter-step sleep, so aborting takes effect mid-step.