-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmulti_agent.py
More file actions
132 lines (99 loc) · 4.18 KB
/
Copy pathmulti_agent.py
File metadata and controls
132 lines (99 loc) · 4.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#!/usr/bin/env python3
"""Multi-agent coordination with filigree.
This example demonstrates how multiple agents can safely coordinate using
filigree's atomic claim_next mechanism. Two simulated agents run concurrently
in threads, each competing to claim and complete tasks from a shared pool.
Key concepts shown:
- Creating tasks with varying priorities
- Using claim_next() for race-safe work acquisition
- Advancing issues through the workflow (claim -> in_progress -> closed)
- Adding comments as an audit trail
- Handling the "no more work" case when claim_next returns None
How to run:
python docs/examples/multi_agent.py
"""
from __future__ import annotations
import tempfile
import threading
import time
from pathlib import Path
from filigree.core import FiligreeDB
def create_work_items(db: FiligreeDB) -> list[str]:
"""Create 5 tasks with varying priorities and return their IDs."""
tasks = [
("Set up CI pipeline", 0), # P0 - Critical
("Write unit tests", 1), # P1 - High
("Update documentation", 2), # P2 - Medium
("Refactor logging module", 3), # P3 - Low
("Add changelog entry", 4), # P4 - Backlog
]
ids = []
for title, priority in tasks:
issue = db.create_issue(title, priority=priority, actor="coordinator")
ids.append(issue.id)
print(f" Created: [{issue.id}] P{priority} - {title}")
return ids
def agent_loop(db: FiligreeDB, agent_name: str) -> None:
"""Simulate an agent that claims and completes tasks in a loop.
Each iteration:
1. Try to claim the next highest-priority ready task
2. If none available, stop
3. Move to in_progress
4. Add a comment documenting the work
5. Close the issue
"""
while True:
# Attempt to claim the highest-priority available task.
# claim_next is atomic -- if two agents race, only one wins.
issue = db.claim_next(agent_name, actor=agent_name)
if issue is None:
print(f" [{agent_name}] No more work available. Shutting down.")
break
print(f" [{agent_name}] Claimed: [{issue.id}] P{issue.priority} - {issue.title}")
# Advance to in_progress
db.update_issue(issue.id, status="in_progress", actor=agent_name)
print(f" [{agent_name}] Started work on: {issue.title}")
# Simulate doing work
time.sleep(0.05)
# Leave an audit trail
db.add_comment(
issue.id,
f"Completed by {agent_name}. All checks passed.",
author=agent_name,
)
# Close the issue
db.close_issue(issue.id, reason="Done", actor=agent_name)
print(f" [{agent_name}] Closed: [{issue.id}] - {issue.title}")
def main() -> None:
# Create a temporary directory for the demo database
with tempfile.TemporaryDirectory(prefix="filigree_demo_") as tmpdir:
db_path = Path(tmpdir) / "demo.db"
# Initialize the database. FiligreeDB handles schema creation,
# migrations, and workflow template seeding automatically.
db = FiligreeDB(db_path, prefix="demo")
db.initialize()
print("=== Multi-Agent Coordination Demo ===\n")
# Step 1: Create a pool of work items
print("Creating work items:")
create_work_items(db)
# Step 2: Launch two agents in parallel threads
print("\nStarting agents:")
agent_a = threading.Thread(target=agent_loop, args=(db, "agent-alpha"))
agent_b = threading.Thread(target=agent_loop, args=(db, "agent-beta"))
agent_a.start()
agent_b.start()
agent_a.join()
agent_b.join()
# Step 3: Show final state
print("\n--- Final State ---")
all_issues = db.list_issues()
for issue in all_issues:
comments = db.get_comments(issue.id)
author = comments[-1]["author"] if comments else "n/a"
print(f" [{issue.id}] {issue.status:<12} P{issue.priority} {issue.title:<30} (completed by: {author})")
stats = db.get_stats()
print(f"\nStats: {stats['by_category']}")
db.close()
print("\nDemo complete. Temp database cleaned up.")
if __name__ == "__main__":
main()