| 397 | |
| 398 | # === SECTION: team (s09/s11) === |
| 399 | class TeammateManager: |
| 400 | def __init__(self, bus: MessageBus, task_mgr: TaskManager): |
| 401 | TEAM_DIR.mkdir(exist_ok=True) |
| 402 | self.bus = bus |
| 403 | self.task_mgr = task_mgr |
| 404 | self.config_path = TEAM_DIR / "config.json" |
| 405 | self.config = self._load() |
| 406 | self.threads = {} |
| 407 | |
| 408 | def _load(self) -> dict: |
| 409 | if self.config_path.exists(): |
| 410 | return json.loads(self.config_path.read_text()) |
| 411 | return {"team_name": "default", "members": []} |
| 412 | |
| 413 | def _save(self): |
| 414 | self.config_path.write_text(json.dumps(self.config, indent=2)) |
| 415 | |
| 416 | def _find(self, name: str) -> dict: |
| 417 | for m in self.config["members"]: |
| 418 | if m["name"] == name: return m |
| 419 | return None |
| 420 | |
| 421 | def spawn(self, name: str, role: str, prompt: str) -> str: |
| 422 | member = self._find(name) |
| 423 | if member: |
| 424 | if member["status"] not in ("idle", "shutdown"): |
| 425 | return f"Error: '{name}' is currently {member['status']}" |
| 426 | member["status"] = "working" |
| 427 | member["role"] = role |
| 428 | else: |
| 429 | member = {"name": name, "role": role, "status": "working"} |
| 430 | self.config["members"].append(member) |
| 431 | self._save() |
| 432 | threading.Thread(target=self._loop, args=(name, role, prompt), daemon=True).start() |
| 433 | return f"Spawned '{name}' (role: {role})" |
| 434 | |
| 435 | def _set_status(self, name: str, status: str): |
| 436 | member = self._find(name) |
| 437 | if member: |
| 438 | member["status"] = status |
| 439 | self._save() |
| 440 | |
| 441 | def _loop(self, name: str, role: str, prompt: str): |
| 442 | team_name = self.config["team_name"] |
| 443 | sys_prompt = (f"You are '{name}', role: {role}, team: {team_name}, at {WORKDIR}. " |
| 444 | f"Use idle when done with current work. You may auto-claim tasks.") |
| 445 | messages = [{"role": "user", "content": prompt}] |
| 446 | tools = [ |
| 447 | {"name": "bash", "description": "Run command.", "input_schema": {"type": "object", "properties": {"command": {"type": "string"}}, "required": ["command"]}}, |
| 448 | {"name": "read_file", "description": "Read file.", "input_schema": {"type": "object", "properties": {"path": {"type": "string"}}, "required": ["path"]}}, |
| 449 | {"name": "write_file", "description": "Write file.", "input_schema": {"type": "object", "properties": {"path": {"type": "string"}, "content": {"type": "string"}}, "required": ["path", "content"]}}, |
| 450 | {"name": "edit_file", "description": "Edit file.", "input_schema": {"type": "object", "properties": {"path": {"type": "string"}, "old_text": {"type": "string"}, "new_text": {"type": "string"}}, "required": ["path", "old_text", "new_text"]}}, |
| 451 | {"name": "send_message", "description": "Send message.", "input_schema": {"type": "object", "properties": {"to": {"type": "string"}, "content": {"type": "string"}}, "required": ["to", "content"]}}, |
| 452 | {"name": "idle", "description": "Signal no more work.", "input_schema": {"type": "object", "properties": {}}}, |
| 453 | {"name": "claim_task", "description": "Claim task by ID.", "input_schema": {"type": "object", "properties": {"task_id": {"type": "integer"}}, "required": ["task_id"]}}, |
| 454 | ] |
| 455 | while True: |
| 456 | # -- WORK PHASE -- |