A creative-writing Agent runs with three observers attached: two built-in (TokenMonitor, LoopDetector) and one custom (AlertConsole). The thresholds are deliberately low so a single ask trips the monitors and the custom observer prints every alert to stdout — giving you a live "watchdog dashboard" view of what the framework is noticing.
"""04 · Token watchdog — observers and alertsDemonstrates three observer patterns running against a single Agent:1. ``TokenMonitor`` — built-in, tallies usage and warns above a threshold.2. ``LoopDetector`` — built-in, spots repetitive tool calls.3. A hand-written ``BaseObserver`` that subscribes to ``ObserverAlert`` and prints a formatted dashboard line every time anything alerts.Run:: .venv-beta/bin/python 04_token_watchdog.py"""importasynciofromautogen.betaimportAgentfromautogen.beta.annotationsimportContextfromautogen.beta.configimportGeminiConfigfromautogen.beta.eventsimportBaseEventfromautogen.beta.events.alertimportObserverAlertfromautogen.beta.observerimportBaseObserver,LoopDetector,TokenMonitorfromautogen.beta.streamimportMemoryStreamfromautogen.beta.watchimportEventWatchdefsection(title:str)->None:print(f"\n── {title} ───")classAlertConsole(BaseObserver):"""Watches the stream for ObserverAlerts and prints them to stdout."""def__init__(self)->None:super().__init__("alert-console",watch=EventWatch(ObserverAlert))self.seen:list[ObserverAlert]=[]asyncdefprocess(self,events:list[BaseEvent],ctx:Context)->None:foreventinevents:ifisinstance(event,ObserverAlert):self.seen.append(event)print(f" [{event.severity.upper():<8}] {event.source}: {event.message}")returnNone# Don't emit a follow-up alertasyncdefmain()->None:config=GeminiConfig(model="gemini-3-flash-preview",temperature=0)section("Watchdog — low thresholds so observers trip on a single ask")token_monitor=TokenMonitor(warn_threshold=50,alert_threshold=5_000)loop_detector=LoopDetector(window_size=5,repeat_threshold=2)console=AlertConsole()stream=MemoryStream()agent=Agent("writer",prompt=("Write prose the user asks for. Favour variety — never repeat the same sentence twice."),config=config,observers=[token_monitor,loop_detector,console],)reply=awaitagent.ask("Write three distinct 30-word paragraphs about springtime in Kyoto.",stream=stream,)print()print("Final reply (truncated):")print(" ",(reply.bodyor"")[:240],"...")print()print(f"Total tokens tracked by TokenMonitor: {token_monitor.total_tokens}")print(f"Alerts emitted this run: {len(console.seen)}")if__name__=="__main__":asyncio.run(main())