Coverage for src / osiris_cli / conversation_history.py: 0%

59 statements  

« prev     ^ index     » next       coverage.py v7.13.0, created at 2025-12-27 17:41 +0200

1#!/usr/bin/env python3 

2""" 

3Conversation History Manager for Osiris CLI 

4Tracks conversation history and enables navigation 

5""" 

6 

7from pathlib import Path 

8from typing import List, Optional 

9import json 

10from datetime import datetime 

11 

12 

13class ConversationHistory: 

14 """Manage conversation history for prompt navigation""" 

15 

16 def __init__(self, agent_name: str = "main"): 

17 self.agent_name = agent_name 

18 self.history_dir = Path.home() / ".osiris" / "history" 

19 self.history_dir.mkdir(parents=True, exist_ok=True) 

20 self.history_file = self.history_dir / f"{agent_name}_history.json" 

21 self.prompts: List[str] = [] 

22 self.current_index: int = -1 

23 self.load() 

24 

25 def load(self): 

26 """Load history from file""" 

27 if self.history_file.exists(): 

28 try: 

29 with open(self.history_file, 'r') as f: 

30 data = json.load(f) 

31 self.prompts = data.get("prompts", []) 

32 except Exception: 

33 self.prompts = [] 

34 

35 def save(self): 

36 """Save history to file""" 

37 try: 

38 with open(self.history_file, 'w') as f: 

39 json.dump({ 

40 "prompts": self.prompts[-1000:], # Keep last 1000 

41 "last_updated": datetime.now().isoformat() 

42 }, f, indent=2) 

43 except Exception: 

44 pass 

45 

46 def add(self, prompt: str): 

47 """Add prompt to history""" 

48 if prompt and prompt.strip(): 

49 # Don't add duplicates of the last prompt 

50 if not self.prompts or self.prompts[-1] != prompt: 

51 self.prompts.append(prompt) 

52 self.save() 

53 # Reset index 

54 self.current_index = len(self.prompts) 

55 

56 def get_previous(self) -> Optional[str]: 

57 """Get previous prompt (arrow up)""" 

58 if not self.prompts: 

59 return None 

60 

61 if self.current_index > 0: 

62 self.current_index -= 1 

63 

64 if 0 <= self.current_index < len(self.prompts): 

65 return self.prompts[self.current_index] 

66 

67 return None 

68 

69 def get_next(self) -> Optional[str]: 

70 """Get next prompt (arrow down)""" 

71 if not self.prompts: 

72 return None 

73 

74 if self.current_index < len(self.prompts) - 1: 

75 self.current_index += 1 

76 return self.prompts[self.current_index] 

77 else: 

78 # At the end, return empty string 

79 self.current_index = len(self.prompts) 

80 return "" 

81 

82 def get_all(self) -> List[str]: 

83 """Get all prompts""" 

84 return self.prompts.copy() 

85 

86 def clear(self): 

87 """Clear history""" 

88 self.prompts = [] 

89 self.current_index = -1 

90 self.save() 

91 

92 def search(self, query: str) -> List[str]: 

93 """Search history for matching prompts""" 

94 query_lower = query.lower() 

95 return [p for p in self.prompts if query_lower in p.lower()] 

96 

97 

98# Global history instance 

99conversation_history = ConversationHistory()