User correctly identified confusing state model in approval workflow:
# Current Design (CONFUSING)
pending_approval: Optional[Dict[str, Any]] = NoneIssues with current design:
pending_approval=Noneis ambiguous - could mean:- No approval needed
- Approval was processed (but was it approved or denied?)
- Approval was cancelled
- Forces polling loop to check command history to determine actual outcome
- Inconsistent with command execution queue's proper status model
@dataclass
class AgentTerminalSession:
pending_approval: Optional[Dict[str, Any]] = None # Dict or None - unclearFlow:
- Approval requested →
pending_approval = {"command": ..., "risk": ..., "reasons": ...} - Approval processed →
pending_approval = None - Must check command history to know if approved or denied
# backend/services/agent_terminal_service.py already uses proper status strings:
status="pending_approval" # Awaiting user decision
status="approved" # User approved
status="denied" # User rejected
status="pre_approved" # Auto-approved by systemfrom enum import Enum
from typing import Optional
class ApprovalStatus(Enum):
"""Explicit approval status states"""
PENDING = "pending" # Awaiting user decision
APPROVED = "approved" # User approved command
DENIED = "denied" # User rejected command
PRE_APPROVED = "pre_approved" # Auto-approved (low risk)
COMMENTED = "commented" # User commented without decision
NONE = None # No approval required
@dataclass
class AgentTerminalSession:
# BEFORE (confusing)
# pending_approval: Optional[Dict[str, Any]] = None
# AFTER (clear)
approval_status: ApprovalStatus = ApprovalStatus.NONE
approval_request: Optional[Dict[str, Any]] = None # Separate field for request details- Clear State Machine: Each state has explicit meaning
- No Ambiguity:
Noneonly means "no approval required" - Type Safety: Enum prevents invalid states
- Self-Documenting: Code clearly shows all possible approval states
- Consistent: Matches command execution queue pattern
- Easier Debugging: Can log exact state without checking history
- Simpler Polling: No need to check command history to determine outcome
@dataclass
class AgentTerminalSession:
# Keep old field for backward compatibility
pending_approval: Optional[Dict[str, Any]] = None
# Add new fields
approval_status: ApprovalStatus = ApprovalStatus.NONE
approval_request: Optional[Dict[str, Any]] = NoneUpdate all code to write to both old and new fields:
# When requesting approval
session.pending_approval = approval_data # OLD
session.approval_status = ApprovalStatus.PENDING # NEW
session.approval_request = approval_data # NEW
# When approving
session.pending_approval = None # OLD
session.approval_status = ApprovalStatus.APPROVED # NEWUpdate all code that reads approval state:
# BEFORE
if session.pending_approval is None:
# Was it approved or denied? Must check history!
# AFTER
if session.approval_status == ApprovalStatus.APPROVED:
# Clear and explicit!
elif session.approval_status == ApprovalStatus.DENIED:
# Also clear!After all reads are migrated, remove pending_approval field.
Files that need updates:
backend/services/agent_terminal_service.py- Main approval logicsrc/chat_workflow_manager.py- Approval pollingautobot-backend/api/agent.py- API endpointsautobot-frontend/src/components/chat/ChatMessages.vue- Frontend approval UI
- Infinite approval polling loop (fixed 2025-11-11, commit 2452aeb)
- Bug was caused by unclear state transitions from
None - New enum design would have prevented this bug
- Bug was caused by unclear state transitions from
Medium-High - While current workaround exists, the confusing state model:
- Makes code harder to understand and maintain
- Increases risk of future bugs
- Wastes CPU cycles checking command history
"pending aproval state none is confusing that would mean there is no state, should be pending, aproved, rejected, and some other state that describes that user comented on command"
Absolutely correct assessment. User identified the exact problem and the proper solution.
Created: 2025-11-11 Status: Design Doc - Awaiting Implementation Priority: Medium-High Effort: Medium (impacts multiple files, needs careful migration)