Add action explanation and follow-up functionality to MachaChatSession

- Introduced `explain_action` method to provide detailed explanations for pending actions in the approval queue.
- Added `answer_action_followup` method to handle user follow-up questions regarding proposed actions.
- Updated `main` function to support discussion mode with action explanations and follow-ups.
- Refactored `conversation.py` to utilize the unified chat implementation from `chat.py`, enhancing compatibility and functionality.
- Enhanced error handling for file operations and user input validation in both new methods.
This commit is contained in:
Lily Miller
2025-10-09 16:42:28 -06:00
parent cc8334f2c5
commit 782dce4b2d
3 changed files with 172 additions and 3 deletions

139
chat.py
View File

@@ -348,10 +348,147 @@ class MachaChatSession:
"""
response = self.process_message(question, verbose=verbose)
return response
def explain_action(self, action_index: int) -> str:
"""Explain a pending action from the approval queue"""
# Get action from approval queue
approval_queue_file = self.agent.state_dir / "approval_queue.json"
if not approval_queue_file.exists():
return "Error: No approval queue found."
try:
with open(approval_queue_file, 'r') as f:
queue = json.load(f)
if not (0 <= action_index < len(queue)):
return f"Error: Action #{action_index} not found in approval queue (queue has {len(queue)} items)."
action_item = queue[action_index]
except Exception as e:
return f"Error reading approval queue: {e}"
action = action_item.get("action", {})
context = action_item.get("context", {})
timestamp = action_item.get("timestamp", "unknown")
# Build explanation prompt
prompt = f"""You are Macha, explaining a proposed system action to the user.
ACTION DETAILS:
- Proposed Action: {action.get('proposed_action', 'N/A')}
- Action Type: {action.get('action_type', 'N/A')}
- Risk Level: {action.get('risk_level', 'N/A')}
- Diagnosis: {action.get('diagnosis', 'N/A')}
- Commands to execute: {', '.join(action.get('commands', []))}
- Timestamp: {timestamp}
SYSTEM CONTEXT:
{json.dumps(context, indent=2)}
Please provide a clear, concise explanation of:
1. What problem was detected
2. What this action will do to fix it
3. Why this approach was chosen
4. Any potential risks or side effects
5. Expected outcome
Be conversational and helpful. Use plain language, not technical jargon unless necessary."""
try:
response = self.agent._query_ollama(prompt, temperature=0.7)
return response
except Exception as e:
return f"Error generating explanation: {e}"
def answer_action_followup(self, action_index: int, user_question: str) -> str:
"""Answer a follow-up question about a pending action"""
# Get action from approval queue
approval_queue_file = self.agent.state_dir / "approval_queue.json"
if not approval_queue_file.exists():
return "Error: No approval queue found."
try:
with open(approval_queue_file, 'r') as f:
queue = json.load(f)
if not (0 <= action_index < len(queue)):
return f"Error: Action #{action_index} not found."
action_item = queue[action_index]
except Exception as e:
return f"Error reading approval queue: {e}"
action = action_item.get("action", {})
context = action_item.get("context", {})
# Build follow-up prompt
prompt = f"""You are Macha, answering a follow-up question about a proposed action.
ACTION SUMMARY:
- Proposed: {action.get('proposed_action', 'N/A')}
- Type: {action.get('action_type', 'N/A')}
- Risk: {action.get('risk_level', 'N/A')}
- Diagnosis: {action.get('diagnosis', 'N/A')}
- Commands: {', '.join(action.get('commands', []))}
SYSTEM CONTEXT:
{json.dumps(context, indent=2)[:2000]}
USER'S QUESTION:
{user_question}
Please answer the user's question clearly and honestly. If you're uncertain about something, say so. Focus on helping them make an informed decision about whether to approve this action."""
try:
response = self.agent._query_ollama(prompt, temperature=0.7)
return response
except Exception as e:
return f"Error: {e}"
def main():
"""Main entry point for macha-chat"""
"""Main entry point for macha-chat and conversation.py"""
# Check for --discuss flag (used by macha-approve discuss)
if "--discuss" in sys.argv:
try:
discuss_index = sys.argv.index("--discuss")
if discuss_index + 1 >= len(sys.argv):
print("Error: --discuss requires an action number", file=sys.stderr)
sys.exit(1)
action_number = int(sys.argv[discuss_index + 1])
session = MachaChatSession()
# Check if this is a follow-up question or initial explanation
if "--follow-up" in sys.argv:
followup_index = sys.argv.index("--follow-up")
if followup_index + 1 >= len(sys.argv):
print("Error: --follow-up requires a question", file=sys.stderr)
sys.exit(1)
# Get the rest of the arguments as the question
question = " ".join(sys.argv[followup_index + 1:])
response = session.answer_action_followup(action_number, question)
print(response)
else:
# Initial explanation
explanation = session.explain_action(action_number)
print(explanation)
return
except (ValueError, IndexError) as e:
print(f"Error: Invalid action number: {e}", file=sys.stderr)
sys.exit(1)
except Exception as e:
print(f"Error: {e}", file=sys.stderr)
sys.exit(1)
# Normal interactive chat mode
session = MachaChatSession()
session.run_interactive()