1use async_trait::async_trait;
5use serde::Deserialize;
6use std::sync::Arc;
7
8use super::traits::*;
9use crate::agent::AgentRunner;
10
11pub struct SessionStatusTool {
13 runner: Arc<AgentRunner>,
14}
15
16impl SessionStatusTool {
17 pub fn new(runner: Arc<AgentRunner>) -> Self {
18 Self { runner }
19 }
20}
21
22#[derive(Deserialize)]
23struct SessionStatusArgs {
24 model: Option<String>,
26}
27
28#[async_trait]
29impl Tool for SessionStatusTool {
30 fn name(&self) -> &str {
31 "session_status"
32 }
33
34 fn spec(&self) -> ToolSpec {
35 ToolSpec {
36 name: "session_status".to_string(),
37 description: "Show session status (current model, tools, uptime). Optionally set model override with model parameter.".to_string(),
38 parameters: serde_json::json!({
39 "type": "object",
40 "properties": {
41 "model": {
42 "type": "string",
43 "description": "Set model override (e.g. 'gpt-5.5', 'gpt-5.4', 'gpt-5.4-mini'). Use 'default' to reset."
44 }
45 }
46 }),
47 }
48 }
49
50 async fn execute(&self, arguments: &str) -> anyhow::Result<ToolResult> {
51 let args: SessionStatusArgs =
52 serde_json::from_str(arguments).unwrap_or(SessionStatusArgs { model: None });
53
54 if let Some(model) = &args.model {
55 if model == "default" || model == "reset" {
56 let default = self.runner.get_default_model().to_string();
57 self.runner.reset_model();
58 return Ok(ToolResult::success(format!(
59 "Model reset to configured default: {default}"
60 )));
61 }
62 self.runner.set_model(model.as_str());
63 return Ok(ToolResult::success(format!("Model switched to: {model}")));
64 }
65
66 let tools = self.runner.list_tools().await;
67 let cfg = &self.runner.agent_config;
68 let status = format!(
69 "Session Status:\n\
70 Model (current): {}\n\
71 Model (default): {}\n\
72 Model (fast): {}\n\
73 Model (heavy): {}\n\
74 Tools: {} active\n\
75 PID: {}\n\
76 Runtime: apollo v{}\n\n\
77 Tool list: {}\n\n\
78 Tip: use session_status{{\"model\":\"...\"}}\n\
79 For swarms — use fast model as runner, heavy as orchestrator.\n\
80 Available aliases: default/reset (restore configured model)",
81 self.runner.get_model(),
82 self.runner.get_default_model(),
83 cfg.fast_model,
84 cfg.heavy_model,
85 tools.len(),
86 std::process::id(),
87 env!("CARGO_PKG_VERSION"),
88 tools.join(", "),
89 );
90
91 Ok(ToolResult::success(status))
92 }
93}