(
&self,
chat_view: &mut ChatView,
chat_state: &mut ChatState,
rt_handle: &tokio::runtime::Handle,
)
| 1774 | } |
| 1775 | |
| 1776 | fn show_usage_report( |
| 1777 | &self, |
| 1778 | chat_view: &mut ChatView, |
| 1779 | chat_state: &mut ChatState, |
| 1780 | rt_handle: &tokio::runtime::Handle, |
| 1781 | ) { |
| 1782 | if chat_state.is_processing { |
| 1783 | chat_view.set_status(Some( |
| 1784 | "Wait until the session is idle before using /usage.".to_string(), |
| 1785 | )); |
| 1786 | return; |
| 1787 | } |
| 1788 | |
| 1789 | let session_id = chat_state.core_session_id.clone(); |
| 1790 | let workspace_path = chat_state |
| 1791 | .workspace |
| 1792 | .clone() |
| 1793 | .or_else(|| self.workspace.clone()) |
| 1794 | .or_else(|| Some(self.agent.workspace_path_string())); |
| 1795 | let token_usage_service = self.token_usage_service.clone(); |
| 1796 | let session_manager = self.agent.coordinator().get_session_manager(); |
| 1797 | |
| 1798 | let report_result: Result<bitfun_core::service::session_usage::SessionUsageReport> = |
| 1799 | tokio::task::block_in_place(|| { |
| 1800 | let session_id = session_id.clone(); |
| 1801 | let workspace_path = workspace_path.clone(); |
| 1802 | let token_usage_service = token_usage_service.clone(); |
| 1803 | let session_manager = session_manager.clone(); |
| 1804 | rt_handle.block_on(async move { |
| 1805 | let workspace_path = workspace_path |
| 1806 | .filter(|path| !path.trim().is_empty()) |
| 1807 | .ok_or_else(|| anyhow!("Workspace path is required for usage reports"))?; |
| 1808 | |
| 1809 | let path_manager = bitfun_core::infrastructure::try_get_path_manager_arc() |
| 1810 | .map_err(|error| anyhow!(error.to_string()))?; |
| 1811 | let persistence_manager = PersistenceManager::new(path_manager) |
| 1812 | .map_err(|error| anyhow!(error.to_string()))?; |
| 1813 | |
| 1814 | let report = generate_session_usage_report( |
| 1815 | &persistence_manager, |
| 1816 | Some(token_usage_service.as_ref()), |
| 1817 | SessionUsageReportRequest { |
| 1818 | session_id: session_id.clone(), |
| 1819 | workspace_path: Some(workspace_path), |
| 1820 | remote_connection_id: None, |
| 1821 | remote_ssh_host: None, |
| 1822 | include_hidden_subagents: true, |
| 1823 | }, |
| 1824 | ) |
| 1825 | .await |
| 1826 | .map_err(|error| anyhow!(error.to_string()))?; |
| 1827 | |
| 1828 | let markdown = render_usage_report_markdown(&report); |
| 1829 | let generated_at = u64::try_from(report.generated_at).unwrap_or_default(); |
| 1830 | let usage_report = serde_json::to_value(&report) |
| 1831 | .map_err(|error| anyhow!("Failed to serialize usage report: {}", error))?; |
| 1832 | let metadata = serde_json::json!({ |
| 1833 | "localCommandKind": "usage_report", |
no test coverage detected