When threads terminate (handler returns None or chain exhausted),
the pump now calls budget_registry.cleanup_thread() to:
- Free memory for completed threads
- Return final budget for logging/billing
- Log token usage at debug level
This ensures budgets don't accumulate for completed conversations.
Also adds:
- has_budget() method to check if thread exists without creating
- Tests for cleanup behavior
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>