Agent Run Cancellation
Cancel a running agent execution from another thread.
This example demonstrates how to cancel a running agent execution by starting an agent run in a separate thread and cancelling it from another thread. It shows proper handling of cancelled responses and thread management.
Example
1"""2Example demonstrating how to cancel a running agent execution.34This example shows how to:51. Start an agent run in a separate thread62. Cancel the run from another thread73. Handle the cancelled response8"""910import threading11import time1213from kern.agent import Agent14from kern.models.openai import OpenAIResponses15from kern.run.agent import RunEvent16from kern.run.base import RunStatus171819def long_running_task(agent: Agent, run_id_container: dict):20 """21 Simulate a long-running agent task that can be cancelled.2223 Args:24 agent: The agent to run25 run_id_container: Dictionary to store the run_id for cancellation2627 Returns:28 Dictionary with run results and status29 """30 # Start the agent run - this simulates a long task31 final_response = None32 content_pieces = []3334 for chunk in agent.run(35 "Write a very long story about a dragon who learns to code. "36 "Make it at least 2000 words with detailed descriptions and dialogue. "37 "Take your time and be very thorough.",38 stream=True,39 ):40 if "run_id" not in run_id_container and chunk.run_id:41 run_id_container["run_id"] = chunk.run_id4243 if chunk.event == RunEvent.run_content:44 print(chunk.content, end="", flush=True)45 content_pieces.append(chunk.content)46 # When the run is cancelled, a `RunEvent.run_cancelled` event is emitted47 elif chunk.event == RunEvent.run_cancelled:48 print(f"\nRun was cancelled: {chunk.run_id}")49 run_id_container["result"] = {50 "status": "cancelled",51 "run_id": chunk.run_id,52 "cancelled": True,53 "content": "".join(content_pieces)[:200] + "..."54 if content_pieces55 else "No content before cancellation",56 }57 return58 elif hasattr(chunk, "status") and chunk.status == RunStatus.completed:59 final_response = chunk6061 # If we get here, the run completed successfully62 if final_response:63 run_id_container["result"] = {64 "status": final_response.status.value65 if final_response.status66 else "completed",67 "run_id": final_response.run_id,68 "cancelled": final_response.status == RunStatus.cancelled,69 "content": ("".join(content_pieces)[:200] + "...")70 if content_pieces71 else "No content",72 }73 else:74 run_id_container["result"] = {75 "status": "unknown",76 "run_id": run_id_container.get("run_id"),77 "cancelled": False,78 "content": ("".join(content_pieces)[:200] + "...")79 if content_pieces80 else "No content",81 }828384def cancel_after_delay(agent: Agent, run_id_container: dict, delay_seconds: int = 3):85 """86 Cancel the agent run after a specified delay.8788 Args:89 agent: The agent whose run should be cancelled90 run_id_container: Dictionary containing the run_id to cancel91 delay_seconds: How long to wait before cancelling92 """93 print(f"Will cancel run in {delay_seconds} seconds...")94 time.sleep(delay_seconds)9596 run_id = run_id_container.get("run_id")97 if run_id:98 print(f"Cancelling run: {run_id}")99 success = agent.cancel_run(run_id)100 if success:101 print(f"Run {run_id} marked for cancellation")102 else:103 print(104 f"Failed to cancel run {run_id} (may not exist or already completed)"105 )106 else:107 print("No run_id found to cancel")108109110def main():111 """Main function demonstrating agent run cancellation."""112113 # Initialize the agent with a model114 agent = Agent(115 name="StorytellerAgent",116 model=OpenAIResponses(id="gpt-5.2"), # Use a model that can generate long responses117 description="An agent that writes detailed stories",118 )119120 print("Starting agent run cancellation example...")121 print("=" * 50)122123 # Container to share run_id between threads124 run_id_container = {}125126 # Start the agent run in a separate thread127 agent_thread = threading.Thread(128 target=lambda: long_running_task(agent, run_id_container), name="AgentRunThread"129 )130131 # Start the cancellation thread132 cancel_thread = threading.Thread(133 target=cancel_after_delay,134 args=(agent, run_id_container, 8), # Cancel after 8 seconds135 name="CancelThread",136 )137138 # Start both threads139 print("Starting agent run thread...")140 agent_thread.start()141142 print("Starting cancellation thread...")143 cancel_thread.start()144145 # Wait for both threads to complete146 print("Waiting for threads to complete...")147 agent_thread.join()148 cancel_thread.join()149150 # Print the results151 print("\n" + "=" * 50)152 print("RESULTS:")153 print("=" * 50)154155 result = run_id_container.get("result")156 if result:157 print(f"Status: {result['status']}")158 print(f"Run ID: {result['run_id']}")159 print(f"Was Cancelled: {result['cancelled']}")160161 if result.get("error"):162 print(f"Error: {result['error']}")163 else:164 print(f"Content Preview: {result['content']}")165166 if result["cancelled"]:167 print("\nSUCCESS: Run was successfully cancelled!")168 else:169 print("\nWARNING: Run completed before cancellation")170 else:171 print("No result obtained - check if cancellation happened during streaming")172173 print("\nExample completed!")174175176if __name__ == "__main__":177 # Run the main example178 main()API Endpoint
Agent runs can be cancelled via the AgentOS API:
1POST /agents/{agent_id}/runs/{run_id}/cancelExample:
1curl --location 'http://localhost:7777/agents/story-writer-agent/runs/123/cancel' \2 --request POSTReference: Cancel Agent Run API