interagent-framework 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
interagent/watchdog.py ADDED
@@ -0,0 +1,140 @@
1
+ """Watchdog script for monitoring new messages and tasks."""
2
+
3
+ import time
4
+ import sys
5
+ from pathlib import Path
6
+ from typing import Set, Callable
7
+
8
+ from .constants import MESSAGES_PENDING_DIR, TASKS_ACTIVE_DIR
9
+ from .utils import load_json
10
+
11
+
12
+ class Watchdog:
13
+ """Monitors the .interagent directory for changes."""
14
+
15
+ def __init__(self, callback: Callable = None, poll_interval: float = 5.0):
16
+ """Initialize watchdog.
17
+
18
+ Args:
19
+ callback: Function to call when changes detected
20
+ poll_interval: How often to check (seconds)
21
+ """
22
+ self.callback = callback or self._default_callback
23
+ self.poll_interval = poll_interval
24
+ self.known_messages: Set[str] = set()
25
+ self.known_tasks: Set[str] = set()
26
+ self.running = False
27
+
28
+ def _default_callback(self, event_type: str, data: dict):
29
+ """Default callback that prints to stdout."""
30
+ if event_type == "new_message":
31
+ print(f"\nšŸ“¬ New message for {data['to']} from {data['from']}")
32
+ print(f" Subject: {data.get('subject', '(no subject)')}")
33
+ print(f" Run: interagent inbox --agent {data['to']}")
34
+ print()
35
+ elif event_type == "new_task":
36
+ print(f"\nšŸ“‹ New task assigned to {data.get('assignee', 'unknown')}")
37
+ print(f" Title: {data.get('title', 'Untitled')}")
38
+ print(f" Run: interagent task show {data['id']}")
39
+ print()
40
+ elif event_type == "task_completed":
41
+ print(f"\nāœ… Task completed: {data.get('title', 'Untitled')}")
42
+ print(f" Ready for review!")
43
+ print()
44
+
45
+ def _scan_messages(self) -> Set[str]:
46
+ """Scan for message files."""
47
+ messages = set()
48
+ if MESSAGES_PENDING_DIR.exists():
49
+ for msg_file in MESSAGES_PENDING_DIR.glob("*.json"):
50
+ messages.add(msg_file.stem)
51
+ return messages
52
+
53
+ def _scan_tasks(self) -> Set[str]:
54
+ """Scan for task files."""
55
+ tasks = set()
56
+ if TASKS_ACTIVE_DIR.exists():
57
+ for task_file in TASKS_ACTIVE_DIR.glob("*.json"):
58
+ tasks.add(task_file.stem)
59
+ return tasks
60
+
61
+ def _get_message_info(self, msg_id: str) -> dict:
62
+ """Get message info."""
63
+ msg_file = MESSAGES_PENDING_DIR / f"{msg_id}.json"
64
+ return load_json(msg_file) or {}
65
+
66
+ def _get_task_info(self, task_id: str) -> dict:
67
+ """Get task info."""
68
+ task_file = TASKS_ACTIVE_DIR / f"{task_id}.json"
69
+ return load_json(task_file) or {}
70
+
71
+ def start(self):
72
+ """Start watching."""
73
+ print("šŸ‘ļø InterAgent Watchdog started")
74
+ print(f" Watching: {MESSAGES_PENDING_DIR}")
75
+ print(f" Watching: {TASKS_ACTIVE_DIR}")
76
+ print(f" Poll interval: {self.poll_interval}s")
77
+ print(" Press Ctrl+C to stop\n")
78
+
79
+ # Initial scan
80
+ self.known_messages = self._scan_messages()
81
+ self.known_tasks = self._scan_tasks()
82
+
83
+ self.running = True
84
+
85
+ try:
86
+ while self.running:
87
+ self._check_once()
88
+ time.sleep(self.poll_interval)
89
+ except KeyboardInterrupt:
90
+ print("\n\nšŸ‘‹ Watchdog stopped")
91
+
92
+ def _check_once(self):
93
+ """Check for changes once."""
94
+ # Check messages
95
+ current_messages = self._scan_messages()
96
+ new_messages = current_messages - self.known_messages
97
+
98
+ for msg_id in new_messages:
99
+ msg_data = self._get_message_info(msg_id)
100
+ self.callback("new_message", msg_data)
101
+
102
+ self.known_messages = current_messages
103
+
104
+ # Check tasks
105
+ current_tasks = self._scan_tasks()
106
+ new_tasks = current_tasks - self.known_tasks
107
+
108
+ for task_id in new_tasks:
109
+ task_data = self._get_task_info(task_id)
110
+ self.callback("new_task", task_data)
111
+
112
+ self.known_tasks = current_tasks
113
+
114
+ def stop(self):
115
+ """Stop watching."""
116
+ self.running = False
117
+
118
+
119
+ def main():
120
+ """CLI entry point for watchdog."""
121
+ import argparse
122
+
123
+ parser = argparse.ArgumentParser(
124
+ description="Watch for InterAgent changes",
125
+ )
126
+ parser.add_argument(
127
+ "--interval", "-i",
128
+ type=float,
129
+ default=5.0,
130
+ help="Poll interval in seconds (default: 5)",
131
+ )
132
+
133
+ args = parser.parse_args()
134
+
135
+ watchdog = Watchdog(poll_interval=args.interval)
136
+ watchdog.start()
137
+
138
+
139
+ if __name__ == "__main__":
140
+ main()