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/__init__.py +23 -0
- interagent/cli.py +982 -0
- interagent/constants.py +49 -0
- interagent/locking.py +147 -0
- interagent/messaging.py +183 -0
- interagent/session.py +129 -0
- interagent/task.py +204 -0
- interagent/templates/__init__.py +35 -0
- interagent/templates/review_request.md +68 -0
- interagent/templates/task_delegation.md +69 -0
- interagent/templates/update_prompt.md +70 -0
- interagent/utils.py +90 -0
- interagent/validator.py +156 -0
- interagent/watchdog.py +140 -0
- interagent_framework-0.1.0.dist-info/METADATA +588 -0
- interagent_framework-0.1.0.dist-info/RECORD +20 -0
- interagent_framework-0.1.0.dist-info/WHEEL +5 -0
- interagent_framework-0.1.0.dist-info/entry_points.txt +4 -0
- interagent_framework-0.1.0.dist-info/licenses/LICENSE +21 -0
- interagent_framework-0.1.0.dist-info/top_level.txt +1 -0
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()
|