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

54 statements  

« prev     ^ index     » next       coverage.py v7.13.0, created at 2025-12-31 05:01 +0200

1import re 

2from pathlib import Path 

3from typing import Optional, Dict, Any 

4 

5class PlanExecutor: 

6 FILE_PATTERN = re.compile(r"(?P<path>(?:[\w.\-/]+/)*[\w.\-]+\.\w+)") 

7 READ_KEYWORDS = {"read", "open", "inspect", "review", "summarize", "check", "show"} 

8 LIST_KEYWORDS = {"list", "show files", "list files", "ls", "tree", "overview"} 

9 DEPTH_PATTERN = re.compile(r"(?:max(?:[_\s-]?depth)|depth)\s*[:=]?\s*(\d+)", re.IGNORECASE) 

10 PATH_PATTERN = re.compile(r"path\s*[:=]\s*['\"]?([^'\"\s]+)['\"]?", re.IGNORECASE) 

11 

12 def interpret_step(self, description: str) -> Optional[Dict[str, Any]]: 

13 text = description.lower() 

14 depth = self._parse_max_depth(description) 

15 explicit_path = self._parse_path(description) 

16 path = explicit_path or "." 

17 if "tree" in text or "structure" in text: 

18 return { 

19 "tool": "get_file_tree", 

20 "args": {"path": path, "max_depth": depth if depth is not None else 2} 

21 } 

22 

23 if any(keyword in text for keyword in self.LIST_KEYWORDS): 

24 if "tree" in text: 

25 return { 

26 "tool": "get_file_tree", 

27 "args": {"path": path, "max_depth": depth if depth is not None else 1} 

28 } 

29 return {"tool": "list_directory", "args": {"path": path}} 

30 

31 path = self._find_existing_file(description) 

32 if path and any(keyword in text for keyword in self.READ_KEYWORDS): 

33 return {"tool": "read_file", "args": {"path": str(path)}} 

34 

35 return None 

36 

37 def _find_existing_file(self, description: str) -> Optional[Path]: 

38 match = self.FILE_PATTERN.search(description) 

39 if not match: 

40 return None 

41 candidate = Path(match.group("path")) 

42 if candidate.exists(): 

43 return candidate.resolve() 

44 candidate = Path.cwd() / match.group("path") 

45 if candidate.exists(): 

46 return candidate.resolve() 

47 return None 

48 

49 def _parse_max_depth(self, text: str) -> Optional[int]: 

50 if not text: 

51 return None 

52 match = self.DEPTH_PATTERN.search(text) 

53 if match: 

54 try: 

55 return max(1, int(match.group(1))) 

56 except ValueError: 

57 return None 

58 return None 

59 

60 def _parse_path(self, text: str) -> Optional[str]: 

61 if not text: 

62 return None 

63 match = self.PATH_PATTERN.search(text) 

64 if not match: 

65 return None 

66 value = match.group(1).strip() 

67 return value or None 

68 

69plan_executor = PlanExecutor()