Team Run Cancellation
Cancel a running team execution from another thread.
This example demonstrates how to cancel a running team execution by starting a team 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 team execution.34This example shows how to:51. Start a team 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 RunStatus17from kern.run.team import TeamRunEvent18from kern.team import Team192021def long_running_task(team: Team, run_id_container: dict):22 """23 Simulate a long-running team task that can be cancelled.2425 Args:26 team: The team to run27 run_id_container: Dictionary to store the run_id for cancellation2829 Returns:30 Dictionary with run results and status31 """32 try:33 # Start the team run - this simulates a long task34 final_response = None35 content_pieces = []3637 for chunk in team.run(38 "Write a very long story about a dragon who learns to code. "39 "Make it at least 2000 words with detailed descriptions and dialogue. "40 "Take your time and be very thorough.",41 stream=True,42 ):43 if "run_id" not in run_id_container and chunk.run_id:44 print(f"Team run started: {chunk.run_id}")45 run_id_container["run_id"] = chunk.run_id4647 if chunk.event in [TeamRunEvent.run_content, RunEvent.run_content]:48 print(chunk.content, end="", flush=True)49 content_pieces.append(chunk.content)50 elif chunk.event == RunEvent.run_cancelled:51 print(f"\nMember run was cancelled: {chunk.run_id}")52 run_id_container["result"] = {53 "status": "cancelled",54 "run_id": chunk.run_id,55 "cancelled": True,56 "content": "".join(content_pieces)[:200] + "..."57 if content_pieces58 else "No content before cancellation",59 }60 return61 elif chunk.event == TeamRunEvent.run_cancelled:62 print(f"\nTeam run was cancelled: {chunk.run_id}")63 run_id_container["result"] = {64 "status": "cancelled",65 "run_id": chunk.run_id,66 "cancelled": True,67 "content": "".join(content_pieces)[:200] + "..."68 if content_pieces69 else "No content before cancellation",70 }71 return72 elif hasattr(chunk, "status") and chunk.status == RunStatus.completed:73 final_response = chunk7475 # If we get here, the run completed successfully76 if final_response:77 run_id_container["result"] = {78 "status": final_response.status.value79 if final_response.status80 else "completed",81 "run_id": final_response.run_id,82 "cancelled": final_response.status == RunStatus.cancelled,83 "content": ("".join(content_pieces)[:200] + "...")84 if content_pieces85 else "No content",86 }87 else:88 run_id_container["result"] = {89 "status": "unknown",90 "run_id": run_id_container.get("run_id"),91 "cancelled": False,92 "content": ("".join(content_pieces)[:200] + "...")93 if content_pieces94 else "No content",95 }9697 except Exception as e:98 print(f"\nException in run: {str(e)}")99 run_id_container["result"] = {100 "status": "error",101 "error": str(e),102 "run_id": run_id_container.get("run_id"),103 "cancelled": True,104 "content": "Error occurred",105 }106107108def cancel_after_delay(team: Team, run_id_container: dict, delay_seconds: int = 3):109 """110 Cancel the team run after a specified delay.111112 Args:113 team: The team whose run should be cancelled114 run_id_container: Dictionary containing the run_id to cancel115 delay_seconds: How long to wait before cancelling116 """117 print(f"Will cancel team run in {delay_seconds} seconds...")118 time.sleep(delay_seconds)119120 run_id = run_id_container.get("run_id")121 if run_id:122 print(f"Cancelling team run: {run_id}")123 success = team.cancel_run(run_id)124 if success:125 print(f"Team run {run_id} marked for cancellation")126 else:127 print(128 f"Failed to cancel team run {run_id} (may not exist or already completed)"129 )130 else:131 print("No run_id found to cancel")132133134def main():135 """Main function demonstrating team run cancellation."""136137 # Create team members138 storyteller_agent = Agent(139 name="StorytellerAgent",140 model=OpenAIResponses(id="gpt-5.2"),141 description="An agent that writes creative stories",142 )143144 editor_agent = Agent(145 name="EditorAgent",146 model=OpenAIResponses(id="gpt-5.2"),147 description="An agent that reviews and improves stories",148 )149150 # Initialize the team with agents151 team = Team(152 name="Storytelling Team",153 members=[storyteller_agent, editor_agent],154 model=OpenAIResponses(id="gpt-5.2"), # Team leader model155 description="A team that collaborates to write detailed stories",156 )157158 print("Starting team run cancellation example...")159 print("=" * 50)160161 # Container to share run_id between threads162 run_id_container = {}163164 # Start the team run in a separate thread165 team_thread = threading.Thread(166 target=lambda: long_running_task(team, run_id_container), name="TeamRunThread"167 )168169 # Start the cancellation thread170 cancel_thread = threading.Thread(171 target=cancel_after_delay,172 args=(team, run_id_container, 8), # Cancel after 8 seconds173 name="CancelThread",174 )175176 # Start both threads177 print("Starting team run thread...")178 team_thread.start()179180 print("Starting cancellation thread...")181 cancel_thread.start()182183 # Wait for both threads to complete184 print("Waiting for threads to complete...")185 team_thread.join()186 cancel_thread.join()187188 # Print the results189 print("\n" + "=" * 50)190 print("RESULTS:")191 print("=" * 50)192193 result = run_id_container.get("result")194 if result:195 print(f"Status: {result['status']}")196 print(f"Run ID: {result['run_id']}")197 print(f"Was Cancelled: {result['cancelled']}")198199 if result.get("error"):200 print(f"Error: {result['error']}")201 else:202 print(f"Content Preview: {result['content']}")203204 if result["cancelled"]:205 print("\nSUCCESS: Team run was successfully cancelled!")206 else:207 print("\nWARNING: Team run completed before cancellation")208 else:209 print("No result obtained - check if cancellation happened during streaming")210211 print("\nTeam cancellation example completed!")212213214if __name__ == "__main__":215 # Run the main example216 main()API Endpoint
Team runs can be cancelled via the AgentOS API:
1POST /teams/{team_id}/runs/{run_id}/cancelExample:
1curl --location 'http://localhost:7777/teams/storytelling-team/runs/456/cancel' \2 --request POSTReference: Cancel Team Run API