feat: add /status command to show runtime info

This commit is contained in:
robbyczgw-cla
2026-03-13 16:36:29 +00:00
parent 58389766a7
commit a628741459
2 changed files with 49 additions and 0 deletions

View File

@@ -7,12 +7,14 @@ import json
import os import os
import re import re
import sys import sys
import time
from contextlib import AsyncExitStack from contextlib import AsyncExitStack
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING, Any, Awaitable, Callable from typing import TYPE_CHECKING, Any, Awaitable, Callable
from loguru import logger from loguru import logger
from nanobot import __version__
from nanobot.agent.context import ContextBuilder from nanobot.agent.context import ContextBuilder
from nanobot.agent.memory import MemoryConsolidator from nanobot.agent.memory import MemoryConsolidator
from nanobot.agent.subagent import SubagentManager from nanobot.agent.subagent import SubagentManager
@@ -78,6 +80,8 @@ class AgentLoop:
self.exec_config = exec_config or ExecToolConfig() self.exec_config = exec_config or ExecToolConfig()
self.cron_service = cron_service self.cron_service = cron_service
self.restrict_to_workspace = restrict_to_workspace self.restrict_to_workspace = restrict_to_workspace
self._start_time = time.time()
self._last_usage: dict[str, int] = {}
self.context = ContextBuilder(workspace) self.context = ContextBuilder(workspace)
self.sessions = session_manager or SessionManager(workspace) self.sessions = session_manager or SessionManager(workspace)
@@ -197,6 +201,11 @@ class AgentLoop:
tools=tool_defs, tools=tool_defs,
model=self.model, model=self.model,
) )
if response.usage:
self._last_usage = {
"prompt_tokens": int(response.usage.get("prompt_tokens", 0) or 0),
"completion_tokens": int(response.usage.get("completion_tokens", 0) or 0),
}
if response.has_tool_calls: if response.has_tool_calls:
if on_progress: if on_progress:
@@ -392,12 +401,49 @@ class AgentLoop:
self.sessions.invalidate(session.key) self.sessions.invalidate(session.key)
return OutboundMessage(channel=msg.channel, chat_id=msg.chat_id, return OutboundMessage(channel=msg.channel, chat_id=msg.chat_id,
content="New session started.") content="New session started.")
if cmd == "/status":
history = session.get_history(max_messages=0)
msg_count = len(history)
active_subs = self.subagents.get_running_count()
uptime_s = int(time.time() - self._start_time)
uptime = (
f"{uptime_s // 3600}h {(uptime_s % 3600) // 60}m"
if uptime_s >= 3600
else f"{uptime_s // 60}m {uptime_s % 60}s"
)
last_in = self._last_usage.get("prompt_tokens", 0)
last_out = self._last_usage.get("completion_tokens", 0)
ctx_used = last_in
ctx_total_tokens = max(self.context_window_tokens, 0)
ctx_pct = int((ctx_used / ctx_total_tokens) * 100) if ctx_total_tokens > 0 else 0
ctx_used_str = f"{ctx_used // 1000}k" if ctx_used >= 1000 else str(ctx_used)
ctx_total_str = f"{ctx_total_tokens // 1024}k" if ctx_total_tokens > 0 else "n/a"
lines = [
f"🐈 nanobot v{__version__}",
f"🧠 Model: {self.model}",
f"📊 Tokens: {last_in} in / {last_out} out",
f"📚 Context: {ctx_used_str}/{ctx_total_str} ({ctx_pct}%)",
f"💬 Session: {msg_count} messages",
f"👾 Subagents: {active_subs} active",
f"🪢 Queue: {self.bus.inbound.qsize()} pending",
f"⏱ Uptime: {uptime}",
]
return OutboundMessage(
channel=msg.channel,
chat_id=msg.chat_id,
content="\n".join(lines),
)
if cmd == "/help": if cmd == "/help":
lines = [ lines = [
"🐈 nanobot commands:", "🐈 nanobot commands:",
"/new — Start a new conversation", "/new — Start a new conversation",
"/stop — Stop the current task", "/stop — Stop the current task",
"/restart — Restart the bot", "/restart — Restart the bot",
"/status — Show bot status",
"/help — Show available commands", "/help — Show available commands",
] ]
return OutboundMessage( return OutboundMessage(

View File

@@ -165,6 +165,7 @@ class TelegramChannel(BaseChannel):
BotCommand("stop", "Stop the current task"), BotCommand("stop", "Stop the current task"),
BotCommand("help", "Show available commands"), BotCommand("help", "Show available commands"),
BotCommand("restart", "Restart the bot"), BotCommand("restart", "Restart the bot"),
BotCommand("status", "Show bot status"),
] ]
def __init__(self, config: TelegramConfig, bus: MessageBus): def __init__(self, config: TelegramConfig, bus: MessageBus):
@@ -223,6 +224,7 @@ class TelegramChannel(BaseChannel):
self._app.add_handler(CommandHandler("new", self._forward_command)) self._app.add_handler(CommandHandler("new", self._forward_command))
self._app.add_handler(CommandHandler("stop", self._forward_command)) self._app.add_handler(CommandHandler("stop", self._forward_command))
self._app.add_handler(CommandHandler("restart", self._forward_command)) self._app.add_handler(CommandHandler("restart", self._forward_command))
self._app.add_handler(CommandHandler("status", self._forward_command))
self._app.add_handler(CommandHandler("help", self._on_help)) self._app.add_handler(CommandHandler("help", self._on_help))
# Add message handler for text, photos, voice, documents # Add message handler for text, photos, voice, documents
@@ -434,6 +436,7 @@ class TelegramChannel(BaseChannel):
"🐈 nanobot commands:\n" "🐈 nanobot commands:\n"
"/new — Start a new conversation\n" "/new — Start a new conversation\n"
"/stop — Stop the current task\n" "/stop — Stop the current task\n"
"/status — Show bot status\n"
"/help — Show available commands" "/help — Show available commands"
) )