v0.3: Commands, Logs, And Approvals [CORE COMPLETED]¶
Implementation Status¶
First slice shipped in 3708d7e:
- Added
backend/agent/g_agent/command/with sharedCommandRouter,CommandContext, and built-in handlers. - Wired chat slash commands and direct CLI agent mode through the same command dispatcher for the implemented command set.
- Added shared quoted-argument parsing and helpful unknown-command responses.
- Added
/logsbacked by task checkpoints with bounded output and obvious secret redaction. - Added
/sessionsand/historyon top of the v0.2 SQLite session store. - Added
/approvepass-through soAgentLoopcan replay pending approvals with the live tool registry, and/denyto clear pending approvals for the current session. - Added tests in
test_slash_command_router.py.
Additional shipped slice:
- Added
security/approval_state.pywith persisted append-only approval state underworkspace/state/approvals.jsonl. - Pending approvals now receive ids that survive process restarts.
/denyupdates persisted approval state when denying id-backed pending approvals.- Added
/approvalsto list current-session pending approval ids. - Added
test_approval_state.py. - Added
security/approval_policy.pywith deterministic risky shell and filesystem classifier examples. AgentLoopnow applies the classifier underapprovalMode=confirmeven when a tool is not explicitly listed intools.riskyTools.- Added
test_approval_policy.py. - Added
/approve session <tool>and/approve always <tool>for narrow session-scoped tool allowlists backed by approval state. - Added
/approvals clear <id>and/approvals clear allto remove pending or allowlisted approval records for the current session. - Pending approval replay remains approve-once: replayed entries are removed from session metadata and marked executed in approval state.
Remaining follow-up:
- Move more legacy handlers from
channels/slash_commands.pyintocommand/builtin.pyonce behavior parity is locked.
Goal¶
Make the owner able to control the agent from chat, CLI, and later Web UI.
User Outcome¶
Commands behave the same across surfaces. Risky actions pause for approval instead of failing mysteriously or requiring broad permissions.
Scope¶
- Normalize slash commands across WhatsApp, Telegram, Discord, CLI, and Web UI.
- Add a shared command router.
- Add recent log inspection from CLI and chat.
- Add dangerous action detection for shell and filesystem tools.
- Track pending approvals per session/chat.
- Let owners approve once, deny, or add a narrow persistent allowlist.
- Surface blocked-command reasons clearly in chat and logs.
- Avoid broad auto-approval until policy is tested.
Minimum Commands¶
/status/logs/new/stop/restart/whoami/sessions/search/approve/deny/tools/memory/skills
Module Targets¶
backend/agent/g_agent/command/router.pybackend/agent/g_agent/command/builtin.pybackend/agent/g_agent/agent/tools/approval.pybackend/agent/g_agent/security/approval_policy.pybackend/agent/g_agent/observability/log_reader.pybackend/agent/g_agent/channels/backend/agent/tests/test_command_router.pybackend/agent/tests/test_approval_policy.py
Acceptance Criteria¶
- Commands parse consistently across CLI and at least one chat channel.
- Unknown commands return helpful responses.
- Risky actions create pending approval records.
/approveresumes or replays the blocked action where possible./denyrecords the decision and instructs the agent to continue safely.- Logs command truncates output and redacts obvious secrets.
Tests¶
- Command parser handles args, quoted strings, and unknown commands.
- Approval policy classifies risky shell/file examples.
- Pending approvals are scoped by session/chat.
- Denied actions do not execute.
- Log output is bounded.
References¶
hermes-agent-ref/tools/approval.pyhermes-agent-ref/agent/skill_commands.py
Agent Handoff¶
Current G-Agent State¶
channels/slash_commands.pyis the current command dispatcher. Do not create a parallel command system; extend the existing dispatcher andg_agent.commandwrapper.- Existing commands include
/new,/reset,/compact,/context,/status,/whoami,/memory,/model,/tools,/cron,/packs,/search,/history,/sessions,/logs,/approve,/deny,/help, and/commands. AgentLoopalready hastool_policy,risky_tools,approval_mode, and_execute_tool_with_policy.- User-facing approval flow has first-class
/approvepass-through,/denysession-metadata clearing, persisted approval state, and/approvalslisting. It still needs richer denied-replay coverage and command-router extraction for the remaining legacy handlers. - Runtime checkpoints already track running tasks and events in
agent/runtime.py;/logsreads them with bounded output and obvious secret redaction./statusenrichment remains follow-up work.
Reference Details To Inspect¶
hermes-agent-ref/tools/approval.py- context-local session key
- pending approval queue per session
- approve once/session/always/deny
- permanent allowlist
- cron unattended denial
- gateway notification callback
nanobot-ref/nanobot/command/router.py- shared command router shape.
nanobot-ref/nanobot/command/builtin.py- built-in command organization.
Implementation Strategy¶
Start by extracting the existing dispatcher into a package, but keep imports compatible.
Recommended shape:
command/router.py: parse command and route to handlers.command/context.py: command context with channel, chat id, session key, sender id, workspace, model, services.command/builtin.py: handlers currently living inSlashCommandDispatcher.channels/slash_commands.py: compatibility wrapper that delegates to new router.security/approval_state.py: persisted pending approvals.security/approval_policy.py: classify risky commands/tool calls.
Implementation Slices¶
- Add command context and parser tests.
- Preserve existing command behavior exactly.
- Move handlers gradually.
- First move
/status,/context,/commands,/help. - Then move session commands.
- Then move memory/model/tools/cron/packs.
- Add
/logs. - Read latest task checkpoint files from
workspace/state/tasks. - Include failed tool calls and provider errors when available.
- Keep output bounded.
- Add approval state.
- Persist under
workspace/state/approvals.jsonlor SQLite once v0.2 exists. - Fields: id, session_key, channel, chat_id, sender_id, tool_name, arguments, reason, created_at, status.
- Add
/approveand/deny. /approveapproves the oldest pending item for current session./approve allapproves all current-session pending items./denydenies oldest.- Return clear text when nothing is pending.
- Integrate with
AgentLoop._execute_tool_with_policy. - When blocked, record pending approval and return a tool result that tells the model not to retry blindly.
Tests To Add¶
test_command_router.py- unknown command behavior
- aliases
- quoted args
- HTML escaping where needed
test_logs_command.py- reads checkpoint failures
- truncates long data
test_approval_state.py- create/list/approve/deny pending approvals
- session scoping
- approve all
test_agent_tool_approval.py- risky tool creates pending approval
- deny does not execute
- approved once executes once
Compatibility Rules¶
- Keep
/searchweb search behavior unless intentionally migrated in a release note. - Keep
/newand/compactbehavior from existing tests. - Do not auto-approve shell commands from natural language.
- Do not store secrets in approval payload previews.
First PR Boundary¶
Extract command router + add /logs + add approval state storage without
rewiring all tools. Second PR wires approval state into tool execution.