| 78 | /// override what they actually want to govern. |
| 79 | #[async_trait] |
| 80 | pub trait BudgetGuard: Send + Sync { |
| 81 | /// Called immediately before an LLM API call. |
| 82 | /// |
| 83 | /// `estimated_prompt_tokens` is a best-effort framework estimate |
| 84 | /// from the message history at call time; impls that want precise |
| 85 | /// accounting should use [`record_after_llm`](Self::record_after_llm) |
| 86 | /// instead of trusting the estimate. |
| 87 | async fn check_before_llm( |
| 88 | &self, |
| 89 | session_id: &str, |
| 90 | estimated_prompt_tokens: usize, |
| 91 | ) -> BudgetDecision { |
| 92 | let _ = (session_id, estimated_prompt_tokens); |
| 93 | BudgetDecision::Allow |
| 94 | } |
| 95 | |
| 96 | /// Called after every successful LLM call with the actual usage |
| 97 | /// reported by the provider. Lets the impl keep its running spend |
| 98 | /// total in sync with reality. |
| 99 | /// |
| 100 | /// Failed LLM calls do not invoke this hook. |
| 101 | async fn record_after_llm(&self, session_id: &str, usage: &TokenUsage) { |
| 102 | let _ = (session_id, usage); |
| 103 | } |
| 104 | |
| 105 | /// Called immediately before a tool invocation. The framework does |
| 106 | /// not pass tool arguments — impls that need argument-aware caps |
| 107 | /// must wrap the executor via a custom `ToolExecutor`. |
| 108 | async fn check_before_tool(&self, session_id: &str, tool_name: &str) -> BudgetDecision { |
| 109 | let _ = (session_id, tool_name); |
| 110 | BudgetDecision::Allow |
| 111 | } |
| 112 | } |
| 113 | |
| 114 | /// Default implementation that always allows everything. Used when no |
| 115 | /// host-supplied guard is configured. |
nothing calls this directly
no outgoing calls
no test coverage detected