Example demonstrating background execution with polling and cancellation.

Background execution allows you to start an agent run that returns immediately.

Background execution allows you to start an agent run that returns immediately with a PENDING status, while the actual work continues in the background. You can then poll for completion or cancel the run.

1"""
2Example demonstrating background execution with polling and cancellation.
3
4Background execution allows you to start an agent run that returns immediately
5with a PENDING status, while the actual work continues in the background.
6You can then poll for completion or cancel the run.
7
8Requirements:
9- PostgreSQL running (./cookbook/scripts/run_pgvector.sh)
10- OPENAI_API_KEY set
11
12Usage:
13 .venvs/demo/bin/python cookbook/02_agents/other/background_execution.py
14"""
15
16import asyncio
17
18from kern.agent import Agent
19from kern.db.postgres import PostgresDb
20from kern.models.openai import OpenAIResponses
21from kern.run.base import RunStatus
22
23# ---------------------------------------------------------------------------
24# Config
25# ---------------------------------------------------------------------------
26
27db = PostgresDb(
28 db_url="postgresql+psycopg://ai:ai@localhost:5532/ai",
29 session_table="background_exec_sessions",
30)
31
32
33# ---------------------------------------------------------------------------
34# Create and Run Background Examples
35# ---------------------------------------------------------------------------
36
37
38async def example_background_run_with_polling():
39 """Start a background run and poll until complete."""
40 print("=" * 60)
41 print("Example 1: Background run with polling")
42 print("=" * 60)
43
44 agent = Agent(
45 name="BackgroundAgent",
46 model=OpenAIResponses(id="gpt-5-mini"),
47 description="An agent that runs in the background",
48 db=db,
49 )
50
51 # Start a background run — returns immediately with PENDING status
52 run_output = await agent.arun(
53 "What is the capital of France? Answer in one sentence.",
54 background=True,
55 )
56
57 print(f"Run ID: {run_output.run_id}")
58 print(f"Session ID: {run_output.session_id}")
59 print(f"Status: {run_output.status}")
60 assert run_output.status == RunStatus.pending, (
61 f"Expected PENDING, got {run_output.status}"
62 )
63
64 # Poll for completion
65 print("\nPolling for completion...")
66 for i in range(30):
67 await asyncio.sleep(1)
68 result = await agent.aget_run_output(
69 run_id=run_output.run_id,
70 session_id=run_output.session_id,
71 )
72 if result is None:
73 print(f" [{i + 1}s] Run not found in DB yet")
74 continue
75
76 print(f" [{i + 1}s] Status: {result.status}")
77
78 if result.status == RunStatus.completed:
79 print(f"\nCompleted! Content: {result.content}")
80 break
81 elif result.status == RunStatus.error:
82 print(f"\nFailed! Content: {result.content}")
83 break
84 else:
85 print("\nTimed out waiting for completion")
86
87 print()
88
89
90async def example_cancel_background_run():
91 """Start a background run and cancel it before completion."""
92 print("=" * 60)
93 print("Example 2: Cancel a background run")
94 print("=" * 60)
95
96 agent = Agent(
97 name="CancellableAgent",
98 model=OpenAIResponses(id="gpt-5-mini"),
99 description="An agent whose run can be cancelled",
100 db=db,
101 )
102
103 # Start a long background run
104 run_output = await agent.arun(
105 "Write a very detailed essay about the history of computing. "
106 "Make it at least 5000 words with sections and subsections.",
107 background=True,
108 )
109
110 print(f"Run ID: {run_output.run_id}")
111 print(f"Status: {run_output.status}")
112
113 # Wait a moment for the run to start
114 await asyncio.sleep(2)
115
116 # Cancel the run
117 print("Cancelling run...")
118 cancelled = await agent.acancel_run(run_id=run_output.run_id)
119 print(f"Cancel result: {cancelled}")
120
121 # Check the final state
122 await asyncio.sleep(1)
123 result = await agent.aget_run_output(
124 run_id=run_output.run_id,
125 session_id=run_output.session_id,
126 )
127 if result:
128 print(f"Final status: {result.status}")
129 print()
130
131
132async def example_cancel_before_start():
133 """Cancel a run before it even starts (cancel-before-start semantics)."""
134 print("=" * 60)
135 print("Example 3: Cancel-before-start")
136 print("=" * 60)
137
138 from kern.run.cancel import cancel_run
139
140 agent = Agent(
141 name="PreCancelAgent",
142 model=OpenAIResponses(id="gpt-5-mini"),
143 description="An agent whose run is cancelled before starting",
144 db=db,
145 )
146
147 # Pre-generate a run ID
148 from uuid import uuid4
149
150 run_id = str(uuid4())
151
152 # Cancel the run BEFORE it starts
153 print(f"Pre-cancelling run {run_id}...")
154 cancel_run(run_id)
155
156 # Now start the run with that ID — it should detect the cancellation
157 run_output = await agent.arun(
158 "This should be cancelled before it runs.",
159 background=True,
160 run_id=run_id,
161 )
162
163 print(f"Run ID: {run_output.run_id}")
164 print(f"Initial status: {run_output.status}")
165
166 # Wait and check — the background task should detect the cancellation
167 await asyncio.sleep(2)
168 result = await agent.aget_run_output(
169 run_id=run_output.run_id,
170 session_id=run_output.session_id,
171 )
172 if result:
173 print(f"Final status: {result.status}")
174 print()
175
176
177async def main():
178 await example_background_run_with_polling()
179 await example_cancel_background_run()
180 await example_cancel_before_start()
181 print("All examples completed!")
182
183
184if __name__ == "__main__":
185 asyncio.run(main())

Run the Example

1# Clone and setup repo
2git clone https://github.com/kern-ai/kern.git
3cd kern/cookbook/02_agents/14_advanced
4
5# Create and activate virtual environment
6./scripts/demo_setup.sh
7source .venvs/demo/bin/activate
8
9# Optiona: Run PgVector (needs docker)
10./cookbook/scripts/run_pgvector.sh
11
12# Export relevant API keys
13export OPENAI_API_KEY="***"
14
15python background_execution.py