Claude Cursor Skill

agent-network

Multi-Agent group chat collaboration system inspired by DingTalk/Lark. Enables AI agents to chat in groups, @mention each other, assign tasks, make decisions via voting, and collaborate. Use when building multi-agent systems that need structured communication, task delegation, de

LLM Mart · 0 points · 0 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download aaaaqwq-agi-super-team-skills_agent-network-cdb04e8.zip · 37 KB
Part of aaaaqwq/agi-super-team — 46 skills

Install

skills CLI npx skills add https://github.com/aAAaqwq/AGI-Super-Team/tree/main/skills/agent-network
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install aaaaqwq-agi-super-team@llmmart
Git git clone https://github.com/aAAaqwq/AGI-Super-Team.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole aaaaqwq/agi-super-team collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

Agent Network - Multi-Agent Collaboration System

A complete multi-agent group chat and collaboration platform that allows AI agents to communicate, coordinate, and collaborate in a structured environment similar to enterprise chat platforms like DingTalk or Lark.

What This Skill Provides

  • Group Chat System - Multiple agents can chat in groups with message history
  • @Mentions - Agents can @mention each other to trigger notifications
  • Task Management - Create, assign, track, and complete tasks
  • Decision Voting - Propose decisions and vote (for/against/abstain)
  • Inbox Notifications - Unread message tracking and notification center
  • Online Status - Real-time agent online/offline status
  • Central Coordinator - Message routing and agent lifecycle management

Quick Start

from agent_network import AgentManager, GroupManager, MessageManager, TaskManager, DecisionManager, get_coordinator

# Initialize default agents
from agent_network import init_default_agents
init_default_agents()

# Get the coordinator
coordinator = get_coordinator()

# Register agents
coordinator.register_agent(agent_id=1)
coordinator.register_agent(agent_id=2)

# Create a group
group = GroupManager.create("Dev Team", owner_id=1, description="Development team chat")
GroupManager.add_member(group.id, agent_id=2)

# Send a message with @mention
MessageManager.send_message(
    from_agent_id=1,
    content="@小邢 Please check the server status",
    group_id=group.id
)

# Assign a task
task = TaskManager.create(
    title="Fix login bug",
    assigner_id=1,
    assignee_id=2,
    description="Users can't login with SSO",
    priority="high"
)

# Create a decision
decision = DecisionManager.create(
    title="Adopt new database?",
    description="Should we migrate to distributed database?",
    proposer_id=1,
    group_id=group.id
)

# Vote on decision
DecisionManager.vote(decision.id, agent_id=2, vote="for", comment="Agreed, better performance")

Core Components

1. Agent Management (agent_manager.py)

Register and manage agents with online/offline status:

from agent_network import AgentManager

# Register new agent
agent = AgentManager.register("NewAgent", "Developer", "Backend specialist")

# Set status
AgentManager.go_online(agent.id)
AgentManager.go_offline(agent.id)

# Get online agents
online = AgentManager.get_online_agents()

2. Group Management (group_manager.py)

Create groups and manage membership:

from agent_network import GroupManager

# Create group
group = GroupManager.create("Project Alpha", owner_id=1)

# Add members
GroupManager.add_member(group.id, agent_id=2)
GroupManager.add_member(group.id, agent_id=3)

# List members
members = GroupManager.get_members(group.id)
online_members = GroupManager.list_online_members(group.id)

3. Message System (message_manager.py)

Send messages with @mention support:

from agent_network import MessageManager

# Send message
msg = MessageManager.send_message(
    from_agent_id=1,
    content="Hello team!",
    group_id=1
)

# @mention automatically detected
msg = MessageManager.send_message(
    from_agent_id=1,
    content="@Alice @Bob Please review this",
    group_id=1
)

# Get message history
messages = MessageManager.get_group_messages(group_id=1, limit=50)

# Search messages
results = MessageManager.search_messages("keyword", group_id=1)

# Get unread count
unread = MessageManager.get_unread_count(agent_id=1)
inbox = MessageManager.get_agent_inbox(agent_id=1, only_unread=True)

4. Task Management (task_manager.py)

Full task lifecycle:

from agent_network import TaskManager

# Create task
task = TaskManager.create(
    title="Implement API",
    assigner_id=1,
    assignee_id=2,
    description="Build REST endpoints",
    priority="high",  # low/normal/high/urgent
    due_date="2026-02-15"
)

# Update status
TaskManager.start_task(task.id, agent_id=2)
TaskManager.complete_task(task.id, agent_id=2, result="All tests passed")

# Add comments
TaskManager.add_comment(task.id, agent_id=2, "50% complete")

# List tasks
all_tasks = TaskManager.get_all()
my_tasks = TaskManager.get_agent_tasks(agent_id=2, status="pending")

5. Decision Voting (decision_manager.py)

Collaborative decision making:

from agent_network import DecisionManager

# Create proposal
decision = DecisionManager.create(
    title="Use microservices?",
    description="Should we refactor to microservices?",
    proposer_id=1,
    group_id=1
)

# Vote
DecisionManager.vote(decision.id, agent_id=2, vote="for", comment="Better scalability")
DecisionManager.vote(decision.id, agent_id=3, vote="against")

# Update status
DecisionManager.update_status(decision.id, "approved", updater_id=1)

# Check results
decision = DecisionManager.get_by_id(decision.id)
print(f"Pass rate: {decision.pass_rate}%")

6. Central Coordinator (coordinator.py)

High-level coordination with automatic message routing:

from agent_network import get_coordinator

coord = get_coordinator()

# Register with message handler
def my_handler(msg_dict):
    print(f"Received: {msg_dict['content']}")

coord.register_agent(agent_id=1, message_handler=my_handler)

# Send through coordinator (auto-routes to handlers)
coord.send_message(from_agent_id=1, content="Hello", group_id=1)

# Task coordination
task = coord.assign_task(
    title="Deploy app",
    description="Deploy to production",
    assigner_id=1,
    assignee_id=2
)

# Decision coordination
decision = coord.propose_decision(
    title="Release v2.0?",
    description="Ready for release?",
    proposer_id=1
)
coord.vote_decision(decision['id'], agent_id=2, vote="for")

CLI Usage

Interactive CLI for testing:

# Run demo
python demo.py

# Interactive CLI
python cli.py

# Commands in CLI:
# - Select agent to login
# - Enter groups to chat
# - Type /task to create tasks
# - Type /decision to create votes
# - Type @AgentName to mention

Default Agents

Six pre-configured agents:

Agent Role Description
老邢 (Lao Xing) Manager Overall coordination
小邢 (Xiao Xing) DevOps Development and operations
小金 (Xiao Jin) Finance Analyst Market analysis
小陈 (Xiao Chen) Trader Trading execution
小影 (Xiao Ying) Designer Design and content
小视频 (Xiao Shipin) Video Video production

Database Schema

SQLite database with tables:

  • agents - Agent profiles and status
  • groups - Group definitions
  • group_members - Membership relations
  • messages - Chat messages with types
  • tasks - Task tracking
  • task_comments - Task discussions
  • decisions - Decision proposals
  • decision_votes - Voting records
  • agent_inbox - Notification inbox

Integration with OpenClaw

Use with sessions_spawn for true multi-agent workflows:

# When a task is assigned, spawn a sub-agent
if new_task:
    sessions_spawn(
        agentId="xiaoxing",
        task=new_task.description,
        label=f"task-{new_task.task_id}"
    )

Files Reference

  • scripts/agent_network/ - Python modules
    • __init__.py - Package exports
    • database.py - SQLite management
    • agent_manager.py - Agent CRUD
    • group_manager.py - Group management
    • message_manager.py - Messaging system
    • task_manager.py - Task management
    • decision_manager.py - Voting system
    • coordinator.py - Central coordinator
  • scripts/cli.py - Interactive CLI
  • scripts/demo.py - Demo script
  • references/schema.sql - Database schema
  • assets/ - Templates (optional)

Advanced Usage

See references/ADVANCED.md for:

  • Custom agent handlers
  • Webhook integrations
  • Message filtering
  • Custom workflows
Files (agi-super-team)
  • .clawhub
    • origin.json 145 B
      {
        "version": 1,
        "registry": "https://clawhub.ai",
        "slug": "agent-network",
        "installedVersion": "1.1.0",
        "installedAt": 1777595359466
      }
      
  • references
    • ADVANCED.md 11.4 KB
      # Advanced Usage Guide for Agent Network
      
      ## Custom Agent Message Handlers
      
      Register agents with custom handlers for true automation:
      
      ```python
      from agent_network import get_coordinator, AgentManager
      
      def create_smart_handler(agent_name, capabilities):
          """Create a handler that responds based on agent capabilities"""
          
          def handler(msg_dict):
              content = msg_dict.get('content', '')
              from_agent = msg_dict.get('from_agent_name', 'Unknown')
              msg_type = msg_dict.get('type', 'chat')
              
              # Check if this agent is mentioned
              if f'@{agent_name}' in content:
                  print(f"[{agent_name}] I was mentioned by {from_agent}!")
                  
                  # Auto-respond based on message type
                  if 'task' in content.lower() and 'dev' in capabilities:
                      print(f"[{agent_name}] 📋 Task-related message detected")
                      
                  elif 'analyze' in content.lower() and 'finance' in capabilities:
                      print(f"[{agent_name}] 📊 Analysis request detected")
                      
                  elif 'design' in content.lower() and 'design' in capabilities:
                      print(f"[{agent_name}] 🎨 Design request detected")
          
          return handler
      
      # Register with smart handlers
      coord = get_coordinator()
      
      dev_agent = AgentManager.get_by_name("小邢")
      if dev_agent:
          coord.register_agent(
              dev_agent.id,
              message_handler=create_smart_handler("小邢", ["dev", "ops"])
          )
      
      finance_agent = AgentManager.get_by_name("小金")
      if finance_agent:
          coord.register_agent(
              finance_agent.id,
              message_handler=create_smart_handler("小金", ["finance", "analyze"])
          )
      ```
      
      ## Webhook Integration
      
      Integrate with external systems via webhooks:
      
      ```python
      import requests
      from agent_network import get_coordinator
      
      class WebhookNotifier:
          def __init__(self, webhook_url):
              self.webhook_url = webhook_url
              self.coord = get_coordinator()
          
          def notify_on_mention(self, msg_dict):
              """Send webhook when agent is mentioned"""
              content = msg_dict.get('content', '')
              
              if '@' in content:  # Someone was mentioned
                  payload = {
                      'event': 'agent_mentioned',
                      'from': msg_dict.get('from_agent_name'),
                      'content': content,
                      'timestamp': msg_dict.get('created_at'),
                      'group': msg_dict.get('group_name')
                  }
                  
                  try:
                      requests.post(self.webhook_url, json=payload, timeout=5)
                  except Exception as e:
                      print(f"Webhook failed: {e}")
          
          def register(self, agent_id):
              """Register webhook handler for an agent"""
              self.coord.register_agent(agent_id, self.notify_on_mention)
      
      # Usage
      notifier = WebhookNotifier("https://hooks.slack.com/services/...")
      notifier.register(agent_id=1)
      ```
      
      ## Message Filtering and Routing
      
      Custom message routing logic:
      
      ```python
      from agent_network import MessageManager, AgentManager
      
      class MessageRouter:
          """Advanced message routing with filtering"""
          
          def __init__(self):
              self.filters = []
              self.routes = {}
          
          def add_filter(self, keyword, target_agent_id):
              """Route messages containing keyword to specific agent"""
              self.filters.append((keyword, target_agent_id))
          
          def route_message(self, msg_dict):
              """Apply routing rules to message"""
              content = msg_dict.get('content', '').lower()
              
              for keyword, target_id in self.filters:
                  if keyword.lower() in content:
                      # Create inbox notification for target agent
                      MessageManager.create_inbox_notification(
                          target_id,
                          msg_dict.get('id')
                      )
                      print(f"Routed message to agent {target_id} (matched: {keyword})")
          
          def auto_assign_tasks(self, msg_dict):
              """Auto-create tasks from certain message patterns"""
              content = msg_dict.get('content', '')
              
              # Pattern: "URGENT: ..." -> Create high priority task
              if content.upper().startswith('URGENT:'):
                  from_agent_id = msg_dict.get('from_agent_id')
                  
                  # Find online DevOps agent
                  online_agents = AgentManager.get_online_agents()
                  dev_agent = next(
                      (a for a in online_agents if 'dev' in a.role.lower()),
                      None
                  )
                  
                  if dev_agent:
                      from agent_network import TaskManager
                      TaskManager.create(
                          title=content[7:50],  # Remove "URGENT:" and truncate
                          assigner_id=from_agent_id,
                          assignee_id=dev_agent.id,
                          description=content,
                          priority="urgent"
                      )
                      print(f"Auto-created urgent task for {dev_agent.name}")
      
      # Usage
      router = MessageRouter()
      router.add_filter("bug", target_agent_id=2)
      router.add_filter("server down", target_agent_id=2)
      router.add_filter("market crash", target_agent_id=3)
      ```
      
      ## Custom Workflows
      
      Build complex multi-agent workflows:
      
      ```python
      from agent_network import (
          get_coordinator, GroupManager, TaskManager,
          DecisionManager, AgentManager
      )
      import time
      
      class DeploymentWorkflow:
          """Automated deployment workflow with approvals"""
          
          def __init__(self):
              self.coord = get_coordinator()
              self.group = None
          
          def setup(self):
              """Create deployment group"""
              manager = AgentManager.get_by_name("老邢")
              dev = AgentManager.get_by_name("小邢")
              
              self.group = GroupManager.create(
                  "🚀 Deployment Team",
                  owner_id=manager.id,
                  description="Production deployment coordination"
              )
              
              GroupManager.add_member(self.group.id, dev.id)
              return self.group
          
          def start_deployment(self, version):
              """Start deployment workflow"""
              manager = AgentManager.get_by_name("老邢")
              
              # Step 1: Create decision for approval
              decision = DecisionManager.create(
                  title=f"Deploy v{version} to Production?",
                  description=f"Ready to deploy version {version}. All tests passed.",
                  proposer_id=manager.id,
                  group_id=self.group.id
              )
              
              print(f"📊 Deployment decision created: {decision.decision_id}")
              print("Waiting for votes...")
              
              return decision
          
          def on_decision_approved(self, decision_id, version):
              """Callback when deployment is approved"""
              manager = AgentManager.get_by_name("老邢")
              dev = AgentManager.get_by_name("小邢")
              
              # Step 2: Create deployment task
              task = TaskManager.create(
                  title=f"Deploy v{version}",
                  assigner_id=manager.id,
                  assignee_id=dev.id,
                  description=f"Execute production deployment for v{version}",
                  group_id=self.group.id,
                  priority="high"
              )
              
              print(f"📋 Deployment task created: {task.task_id}")
              
              # Step 3: Auto-start task
              TaskManager.start_task(task.id, dev.id)
              print("🚀 Deployment started!")
              
              return task
          
          def complete_deployment(self, task_id, version):
              """Mark deployment complete"""
              dev = AgentManager.get_by_name("小邢")
              
              TaskManager.complete_task(
                  task_id,
                  dev.id,
                  result=f"v{version} successfully deployed"
              )
              
              # Broadcast success
              self.coord.broadcast_system_message(
                  f"🎉 v{version} is now live!",
                  group_id=self.group.id
              )
      
      # Usage
      workflow = DeploymentWorkflow()
      group = workflow.setup()
      decision = workflow.start_deployment("2.5.0")
      
      # Later, when decision is approved:
      # workflow.on_decision_approved(decision.id, "2.5.0")
      ```
      
      ## Scheduled Tasks with Cron
      
      Integrate with cron for scheduled operations:
      
      ```python
      from datetime import datetime, timedelta
      from agent_network import TaskManager, AgentManager
      
      class ScheduledTaskManager:
          """Manage recurring tasks"""
          
          def __init__(self):
              self.scheduled = []
          
          def schedule_daily_report(self, assignee_name="小金"):
              """Schedule daily market report task"""
              agent = AgentManager.get_by_name(assignee_name)
              if not agent:
                  return
              
              # Create task for tomorrow morning
              tomorrow = (datetime.now() + timedelta(days=1)).strftime("%Y-%m-%d")
              
              task = TaskManager.create(
                  title=f"Daily Market Report - {tomorrow}",
                  assigner_id=agent.id,  # Self-assigned
                  assignee_id=agent.id,
                  description="Generate and distribute daily market analysis",
                  due_date=tomorrow,
                  priority="normal"
              )
              
              print(f"📅 Scheduled daily report: {task.task_id}")
              return task
          
          def schedule_weekly_review(self, group_id=None):
              """Schedule weekly team review"""
              manager = AgentManager.get_by_name("老邢")
              
              # Find next Friday
              today = datetime.now()
              friday = today + timedelta(days=(4 - today.weekday()) % 7)
              
              task = TaskManager.create(
                  title=f"Weekly Team Review - Week {friday.isocalendar()[1]}",
                  assigner_id=manager.id,
                  assignee_id=manager.id,
                  description="Review team progress and plan next week",
                  due_date=friday.strftime("%Y-%m-%d"),
                  priority="normal",
                  group_id=group_id
              )
              
              print(f"📅 Scheduled weekly review: {task.task_id}")
              return task
      
      # Usage with OpenClaw cron
      # cron.add(job={...}) to schedule these daily/weekly
      ```
      
      ## Persistence and State Management
      
      Handle agent state across sessions:
      
      ```python
      import json
      import os
      from agent_network import AgentManager
      
      class AgentStateManager:
          """Persist agent states to disk"""
          
          def __init__(self, state_dir="./agent_states"):
              self.state_dir = state_dir
              os.makedirs(state_dir, exist_ok=True)
          
          def save_state(self, agent_id, state_dict):
              """Save agent state"""
              filepath = os.path.join(self.state_dir, f"agent_{agent_id}.json")
              with open(filepath, 'w') as f:
                  json.dump(state_dict, f, indent=2)
          
          def load_state(self, agent_id):
              """Load agent state"""
              filepath = os.path.join(self.state_dir, f"agent_{agent_id}.json")
              if os.path.exists(filepath):
                  with open(filepath, 'r') as f:
                      return json.load(f)
              return {}
          
          def restore_all_agents(self):
              """Restore all agent states from disk"""
              for filename in os.listdir(self.state_dir):
                  if filename.startswith("agent_") and filename.endswith(".json"):
                      agent_id = int(filename.split("_")[1].split(".")[0])
                      state = self.load_state(agent_id)
                      
                      # Restore status
                      if state.get('status') == 'online':
                          AgentManager.go_online(agent_id)
                      
                      print(f"Restored state for agent {agent_id}")
      
      # Usage
      state_mgr = AgentStateManager()
      
      # Before shutdown, save states
      for agent in AgentManager.get_all():
          state_mgr.save_state(agent.id, {
              'status': agent.status,
              'last_active': agent.last_active,
              'current_tasks': [...]
          })
      
      # On startup, restore
      state_mgr.restore_all_agents()
      ```
      
    • schema.sql 5.8 KB · in bundle
  • scripts
    • agent_network
      • agent_manager.py 4.8 KB
        #!/usr/bin/env python3
        """
        Agent 群聊协作系统 - Agent 管理模块
        负责 Agent 的注册、登录、状态管理等
        """
        
        from datetime import datetime
        from typing import Optional, List, Dict, Any
        import sqlite3
        import sys
        import os
        sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
        
        try:
            from database import db
        except ImportError:
            from .database import db
        
        
        class Agent:
            """Agent 类"""
            
            def __init__(self, id: int = None, agent_id: int = None, name: str = "", role: str = "", 
                         description: str = "", status: str = "offline", created_at: str = "", 
                         last_active: str = "", **kwargs):
                self.id = id if id is not None else agent_id
                self.name = name
                self.role = role
                self.description = description
                self.status = status
                self.created_at = created_at
                self.last_active = last_active
            
            def to_dict(self) -> Dict[str, Any]:
                return {
                    'id': self.id,
                    'name': self.name,
                    'role': self.role,
                    'description': self.description,
                    'status': self.status,
                    'created_at': self.created_at,
                    'last_active': self.last_active
                }
            
            def __repr__(self):
                return f"Agent({self.name} - {self.role})"
        
        
        class AgentManager:
            """Agent 管理器"""
            
            @staticmethod
            def register(name: str, role: str, description: str = "") -> Optional[Agent]:
                """注册新 Agent"""
                try:
                    agent_id = db.insert(
                        "INSERT INTO agents (name, role, description, status, last_active) VALUES (?, ?, ?, 'offline', ?)",
                        (name, role, description, datetime.now().isoformat())
                    )
                    return AgentManager.get_by_id(agent_id)
                except sqlite3.IntegrityError:
                    print(f"Agent '{name}' 已存在")
                    return None
            
            @staticmethod
            def get_by_id(agent_id: int) -> Optional[Agent]:
                """通过 ID 获取 Agent"""
                row = db.fetch_one("SELECT * FROM agents WHERE id = ?", (agent_id,))
                if row:
                    return Agent(**row)
                return None
            
            @staticmethod
            def get_by_name(name: str) -> Optional[Agent]:
                """通过名称获取 Agent"""
                row = db.fetch_one("SELECT * FROM agents WHERE name = ?", (name,))
                if row:
                    return Agent(**row)
                return None
            
            @staticmethod
            def get_all() -> List[Agent]:
                """获取所有 Agent"""
                rows = db.fetch_all("SELECT * FROM agents ORDER BY created_at")
                return [Agent(**row) for row in rows]
            
            @staticmethod
            def update_status(agent_id: int, status: str) -> bool:
                """更新 Agent 状态"""
                valid_status = ['online', 'offline', 'busy']
                if status not in valid_status:
                    return False
                
                affected = db.execute(
                    "UPDATE agents SET status = ?, last_active = ? WHERE id = ?",
                    (status, datetime.now().isoformat(), agent_id)
                )
                return affected > 0
            
            @staticmethod
            def go_online(agent_id: int) -> bool:
                """Agent 上线"""
                return AgentManager.update_status(agent_id, 'online')
            
            @staticmethod
            def go_offline(agent_id: int) -> bool:
                """Agent 下线"""
                return AgentManager.update_status(agent_id, 'offline')
            
            @staticmethod
            def set_busy(agent_id: int) -> bool:
                """设置 Agent 忙碌状态"""
                return AgentManager.update_status(agent_id, 'busy')
            
            @staticmethod
            def delete(agent_id: int) -> bool:
                """删除 Agent"""
                affected = db.execute("DELETE FROM agents WHERE id = ?", (agent_id,))
                return affected > 0
            
            @staticmethod
            def get_online_agents() -> List[Agent]:
                """获取在线 Agent 列表"""
                rows = db.fetch_all("SELECT * FROM agents WHERE status = 'online' ORDER BY last_active DESC")
                return [Agent(**row) for row in rows]
        
        
        # 初始化默认 Agent 列表
        def init_default_agents():
            """初始化默认 Agent"""
            default_agents = [
                ("老邢", "总管", "负责整体协调和决策"),
                ("小邢", "开发运维", "负责系统开发和运维"),
                ("小金", "金融市场分析", "负责金融市场分析和研究"),
                ("小陈", "美股交易", "负责美股交易执行"),
                ("小影", "设计/短视频", "负责设计和短视频内容"),
                ("小视频", "视频制作", "负责视频制作和后期"),
            ]
            
            for name, role, desc in default_agents:
                agent = AgentManager.get_by_name(name)
                if not agent:
                    AgentManager.register(name, role, desc)
                    print(f"已创建 Agent: {name} ({role})")
        
        
        if __name__ == "__main__":
            init_default_agents()
            print("\n所有 Agent 列表:")
            for agent in AgentManager.get_all():
                print(f"  - {agent}")
        
      • coordinator.py 12.8 KB
        #!/usr/bin/env python3
        """
        Agent 群聊协作系统 - 中央协调器
        负责系统整体协调、消息路由、Agent 调度等
        """
        
        import os
        import sys
        import json
        import time
        import threading
        from datetime import datetime
        from typing import Optional, List, Dict, Any, Callable
        from dataclasses import dataclass, field
        
        # 添加父目录到路径
        sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
        sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
        
        from database import Database, db
        from agent_manager import AgentManager, Agent
        from message_manager import MessageManager, Message, MessageFormatter
        from group_manager import GroupManager, Group
        from task_manager import TaskManager, TaskStatus, TaskPriority
        from decision_manager import DecisionManager, DecisionStatus, VoteType
        
        
        @dataclass
        class AgentSession:
            """Agent 会话状态"""
            agent: Agent
            last_heartbeat: float = field(default_factory=time.time)
            is_active: bool = True
            current_group_id: Optional[int] = None
            handler: Optional[Callable] = None
        
        
        class Coordinator:
            """
            Agent 群聊协作系统中央协调器
            负责:
            1. Agent 生命周期管理
            2. 消息路由和分发
            3. @提及通知处理
            4. 任务调度
            5. 决策流程管理
            """
            
            _instance = None
            
            def __new__(cls):
                if cls._instance is None:
                    cls._instance = super().__new__(cls)
                    cls._instance._initialized = False
                return cls._instance
            
            def __init__(self):
                if self._initialized:
                    return
                
                self._initialized = True
                self.sessions: Dict[int, AgentSession] = {}  # agent_id -> session
                self.message_handlers: Dict[int, List[Callable]] = {}  # agent_id -> handlers
                self.running = False
                self.coordinator_thread = None
                self.check_interval = 5  # 心跳检查间隔(秒)
                
                # 确保默认 Agent 存在
                self._init_default_agents()
            
            def _init_default_agents(self):
                """初始化默认 Agent"""
                default_agents = [
                    ("老邢", "总管", "负责整体协调和决策"),
                    ("小邢", "开发运维", "负责系统开发和运维"),
                    ("小金", "金融市场分析", "负责金融市场分析和研究"),
                    ("小陈", "美股交易", "负责美股交易执行"),
                    ("小影", "设计/短视频", "负责设计和短视频内容"),
                    ("小视频", "视频制作", "负责视频制作和后期"),
                ]
                
                for name, role, desc in default_agents:
                    agent = AgentManager.get_by_name(name)
                    if not agent:
                        AgentManager.register(name, role, desc)
                        print(f"[协调器] 已创建 Agent: {name} ({role})")
            
            def register_agent(self, agent_id: int, message_handler: Optional[Callable] = None) -> bool:
                """注册 Agent 到协调器"""
                agent = AgentManager.get_by_id(agent_id)
                if not agent:
                    print(f"[协调器] Agent {agent_id} 不存在")
                    return False
                
                # 更新状态为在线
                AgentManager.go_online(agent_id)
                
                # 创建会话
                session = AgentSession(agent=agent, handler=message_handler)
                self.sessions[agent_id] = session
                
                # 注册消息处理器
                if message_handler:
                    if agent_id not in self.message_handlers:
                        self.message_handlers[agent_id] = []
                    self.message_handlers[agent_id].append(message_handler)
                
                print(f"[协调器] Agent '{agent.name}' 已注册并上线")
                
                # 发送系统通知
                self.broadcast_system_message(f"Agent '{agent.name}' 已上线")
                
                return True
            
            def unregister_agent(self, agent_id: int) -> bool:
                """从协调器注销 Agent"""
                if agent_id not in self.sessions:
                    return False
                
                agent_name = self.sessions[agent_id].agent.name
                
                # 更新状态为离线
                AgentManager.go_offline(agent_id)
                
                # 移除会话
                del self.sessions[agent_id]
                if agent_id in self.message_handlers:
                    del self.message_handlers[agent_id]
                
                print(f"[协调器] Agent '{agent_name}' 已注销")
                
                # 发送系统通知
                self.broadcast_system_message(f"Agent '{agent_name}' 已下线")
                
                return True
            
            def send_message(self, from_agent_id: int, content: str,
                             group_id: Optional[int] = None,
                             to_agent_id: Optional[int] = None,
                             msg_type: str = "chat") -> Optional[Message]:
                """发送消息"""
                # 验证发送者
                if from_agent_id not in self.sessions:
                    print(f"[协调器] Agent {from_agent_id} 未注册")
                    return None
                
                # 发送消息
                msg = MessageManager.send_message(
                    from_agent_id=from_agent_id,
                    content=content,
                    group_id=group_id,
                    to_agent_id=to_agent_id,
                    msg_type=msg_type
                )
                
                if msg:
                    # 触发消息处理
                    self._route_message(msg)
                
                return msg
            
            def _route_message(self, msg: Message):
                """路由消息到相关 Agent"""
                # 获取消息中 @提及的 Agent
                mentioned_agents = MessageManager.detect_mentions(msg.content)
                
                # 通知被 @提及的 Agent
                for agent in mentioned_agents:
                    if agent.id in self.sessions:
                        self._notify_agent(agent.id, msg)
                
                # 如果是私信,通知接收者
                if msg.to_agent_id and msg.to_agent_id in self.sessions:
                    self._notify_agent(msg.to_agent_id, msg)
                
                # 触发处理器
                handlers_to_call = []
                
                # 收集相关处理器
                for agent_id, handlers in self.message_handlers.items():
                    if agent_id == msg.from_agent_id:
                        continue  # 不通知发送者自己
                    
                    # 检查是否是目标接收者
                    should_notify = False
                    
                    if msg.to_agent_id and msg.to_agent_id == agent_id:
                        should_notify = True
                    elif any(a.id == agent_id for a in mentioned_agents):
                        should_notify = True
                    elif msg.group_id:
                        # 群组消息 - 通知所有在线的群组成员
                        should_notify = True
                    
                    if should_notify:
                        handlers_to_call.extend(handlers)
                
                # 异步调用处理器
                for handler in handlers_to_call:
                    try:
                        threading.Thread(target=handler, args=(msg.to_dict(),), daemon=True).start()
                    except Exception as e:
                        print(f"[协调器] 消息处理器错误: {e}")
            
            def _notify_agent(self, agent_id: int, msg: Message):
                """通知特定 Agent"""
                if agent_id in self.sessions:
                    session = self.sessions[agent_id]
                    session.last_heartbeat = time.time()
                    
                    # 标记消息为已读(如果 Agent 在线)
                    MessageManager.mark_as_read(agent_id, msg.id)
            
            def broadcast_system_message(self, content: str, group_id: Optional[int] = None):
                """广播系统消息"""
                # 获取系统 Agent(老邢作为总管)
                system_agent = AgentManager.get_by_name("老邢")
                if not system_agent:
                    return
                
                MessageManager.send_message(
                    from_agent_id=system_agent.id,
                    content=f"[系统] {content}",
                    group_id=group_id,
                    msg_type="system"
                )
            
            def create_group(self, name: str, owner_id: int, description: str = "") -> Optional[Group]:
                """创建群组"""
                return GroupManager.create(name, owner_id, description)
            
            def join_group(self, agent_id: int, group_id: int) -> bool:
                """Agent 加入群组"""
                return GroupManager.add_member(group_id, agent_id)
            
            def leave_group(self, agent_id: int, group_id: int) -> bool:
                """Agent 离开群组"""
                return GroupManager.remove_member(group_id, agent_id)
            
            def assign_task(self, title: str, description: str,
                            assigner_id: int, assignee_id: int,
                            group_id: Optional[int] = None,
                            priority: str = "normal",
                            due_date: Optional[str] = None) -> Optional[Dict]:
                """指派任务"""
                task = TaskManager.create(
                    title=title,
                    description=description,
                    assigner_id=assigner_id,
                    assignee_id=assignee_id,
                    group_id=group_id,
                    priority=priority,
                    due_date=due_date
                )
                return task.to_dict() if task else None
            
            def complete_task(self, task_id: str, agent_id: int, result: str = "") -> bool:
                """完成任务"""
                return TaskManager.complete_task(task_id, agent_id, result)
            
            def propose_decision(self, title: str, description: str,
                                 proposer_id: int,
                                 group_id: Optional[int] = None) -> Optional[Dict]:
                """提出决策"""
                decision = DecisionManager.propose(title, description, proposer_id, group_id)
                return decision.to_dict() if decision else None
            
            def vote_decision(self, decision_id: str, agent_id: int,
                              vote: str, comment: str = "") -> bool:
                """投票决策"""
                return DecisionManager.vote(decision_id, agent_id, vote, comment)
            
            def finalize_decision(self, decision_id: str) -> Optional[Dict]:
                """结束决策投票"""
                decision = DecisionManager.finalize(decision_id)
                return decision.to_dict() if decision else None
            
            def get_agent_inbox(self, agent_id: int, only_unread: bool = False) -> List[Dict]:
                """获取 Agent 收件箱"""
                return MessageManager.get_agent_inbox(agent_id, only_unread)
            
            def get_unread_count(self, agent_id: int) -> int:
                """获取未读消息数"""
                return MessageManager.get_unread_count(agent_id)
            
            def get_online_agents(self) -> List[Dict]:
                """获取在线 Agent 列表"""
                agents = AgentManager.get_online_agents()
                return [a.to_dict() for a in agents]
            
            def start(self):
                """启动协调器"""
                if self.running:
                    return
                
                self.running = True
                self.coordinator_thread = threading.Thread(target=self._run, daemon=True)
                self.coordinator_thread.start()
                print("[协调器] 已启动")
            
            def stop(self):
                """停止协调器"""
                self.running = False
                if self.coordinator_thread:
                    self.coordinator_thread.join(timeout=5)
                print("[协调器] 已停止")
            
            def _run(self):
                """协调器主循环"""
                while self.running:
                    time.sleep(self.check_interval)
                    self._check_heartbeats()
            
            def _check_heartbeats(self):
                """检查 Agent 心跳"""
                current_time = time.time()
                timeout = 60  # 60秒无心跳视为离线
                
                for agent_id, session in list(self.sessions.items()):
                    if current_time - session.last_heartbeat > timeout:
                        print(f"[协调器] Agent '{session.agent.name}' 心跳超时,标记为离线")
                        AgentManager.go_offline(agent_id)
                        session.is_active = False
        
        
        # 便捷函数
        def get_coordinator() -> Coordinator:
            """获取协调器单例"""
            return Coordinator()
        
        
        # 用于演示的示例 Agent 处理器
        def demo_message_handler(agent_name: str):
            """创建示例消息处理器"""
            def handler(msg_dict: Dict):
                print(f"\n[{agent_name} 收到消息]")
                print(f"  来自: {msg_dict.get('from_agent_name', 'Unknown')}")
                print(f"  内容: {msg_dict.get('content', '')[:50]}...")
                print(f"  类型: {msg_dict.get('type', 'chat')}")
                print()
            
            return handler
        
        
        if __name__ == "__main__":
            # 简单测试
            coord = get_coordinator()
            coord.start()
            
            # 获取 Agent
            lao_xing = AgentManager.get_by_name("老邢")
            xiao_xing = AgentManager.get_by_name("小邢")
            
            if lao_xing and xiao_xing:
                # 注册 Agent
                coord.register_agent(lao_xing.id, demo_message_handler("老邢"))
                coord.register_agent(xiao_xing.id, demo_message_handler("小邢"))
                
                # 发送测试消息
                coord.send_message(lao_xing.id, "@小邢 测试一下系统", msg_type="chat")
                
                # 创建任务
                task = coord.assign_task(
                    title="检查服务器状态",
                    description="请检查所有服务器的运行状态",
                    assigner_id=lao_xing.id,
                    assignee_id=xiao_xing.id,
                    priority="high"
                )
                print(f"创建任务: {task}")
                
                time.sleep(2)
            
            coord.stop()
        
      • database.py 3.3 KB
        #!/usr/bin/env python3
        """
        Agent 群聊协作系统 - 数据库管理模块
        负责数据库连接、初始化和基本操作
        """
        
        import sqlite3
        import os
        from datetime import datetime
        from typing import Optional, List, Dict, Any
        from contextlib import contextmanager
        
        
        class Database:
            """数据库管理类"""
            
            def __init__(self, db_path: str = "data/agent_network.db"):
                self.db_path = db_path
                # 确保目录存在
                os.makedirs(os.path.dirname(db_path), exist_ok=True)
                self.init_database()
            
            @contextmanager
            def get_connection(self):
                """获取数据库连接上下文管理器"""
                conn = sqlite3.connect(self.db_path)
                conn.row_factory = sqlite3.Row  # 使结果可以通过列名访问
                try:
                    yield conn
                    conn.commit()
                except Exception as e:
                    conn.rollback()
                    raise e
                finally:
                    conn.close()
            
            def init_database(self):
                """初始化数据库,执行 schema.sql"""
                # Try multiple possible locations for schema.sql
                possible_paths = [
                    os.path.join(os.path.dirname(__file__), '..', '..', 'references', 'schema.sql'),  # Skill structure
                    os.path.join(os.path.dirname(__file__), '..', 'schema.sql'),  # Local dev
                    os.path.join(os.path.dirname(__file__), '..', '..', 'schema.sql'),  # Alternate
                ]
                
                schema_path = None
                for path in possible_paths:
                    if os.path.exists(path):
                        schema_path = path
                        break
                
                if os.path.exists(schema_path):
                    with open(schema_path, 'r', encoding='utf-8') as f:
                        schema = f.read()
                    
                    with self.get_connection() as conn:
                        conn.executescript(schema)
                else:
                    print(f"警告: 未找到 schema.sql 文件: {schema_path}")
            
            def execute(self, query: str, params: tuple = ()) -> int:
                """执行 SQL 语句,返回影响的行数"""
                with self.get_connection() as conn:
                    cursor = conn.execute(query, params)
                    return cursor.rowcount
            
            def execute_many(self, query: str, params_list: List[tuple]) -> int:
                """批量执行 SQL 语句"""
                with self.get_connection() as conn:
                    cursor = conn.executemany(query, params_list)
                    return cursor.rowcount
            
            def fetch_one(self, query: str, params: tuple = ()) -> Optional[Dict[str, Any]]:
                """查询单条记录"""
                with self.get_connection() as conn:
                    cursor = conn.execute(query, params)
                    row = cursor.fetchone()
                    if row:
                        return dict(row)
                    return None
            
            def fetch_all(self, query: str, params: tuple = ()) -> List[Dict[str, Any]]:
                """查询多条记录"""
                with self.get_connection() as conn:
                    cursor = conn.execute(query, params)
                    rows = cursor.fetchall()
                    return [dict(row) for row in rows]
            
            def insert(self, query: str, params: tuple = ()) -> int:
                """插入记录,返回自增ID"""
                with self.get_connection() as conn:
                    cursor = conn.execute(query, params)
                    return cursor.lastrowid
        
        
        # 全局数据库实例
        db = Database()
        
      • decision_manager.py 13.3 KB
        #!/usr/bin/env python3
        """
        Agent 群聊协作系统 - 决策投票模块
        负责决策提议的创建、投票、结果统计等
        """
        
        from datetime import datetime
        from typing import Optional, List, Dict, Any
        import sys
        import os
        sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
        
        try:
            from database import db
            from agent_manager import AgentManager
            from message_manager import MessageManager
        except ImportError:
            from .database import db
            from .agent_manager import AgentManager
            from .message_manager import MessageManager
        
        
        class DecisionStatus:
            """决策状态常量"""
            PROPOSED = "proposed"
            DISCUSSING = "discussing"
            APPROVED = "approved"
            REJECTED = "rejected"
            IMPLEMENTED = "implemented"
        
        
        class VoteType:
            """投票类型常量"""
            FOR = "for"
            AGAINST = "against"
            ABSTAIN = "abstain"
        
        
        class Decision:
            """决策类"""
            
            def __init__(self, id: int = None, decision_db_id: int = None, decision_id: str = "",
                         title: str = "", description: str = "", group_id: Optional[int] = None,
                         proposer_id: int = None, status: str = "proposed", votes_for: int = 0,
                         votes_against: int = 0, decided_at: Optional[str] = None,
                         created_at: str = "", **kwargs):
                self.id = id if id is not None else decision_db_id
                self.decision_id = decision_id
                self.title = title
                self.description = description
                self.group_id = group_id
                self.proposer_id = proposer_id
                self.status = status
                self.votes_for = votes_for
                self.votes_against = votes_against
                self.decided_at = decided_at
                self.created_at = created_at
                
                # 额外字段
                self.proposer_name: Optional[str] = kwargs.get('proposer_name')
                self.group_name: Optional[str] = kwargs.get('group_name')
                self.votes: List[Dict] = []
            
            def to_dict(self) -> Dict[str, Any]:
                return {
                    'id': self.id,
                    'decision_id': self.decision_id,
                    'title': self.title,
                    'description': self.description,
                    'group_id': self.group_id,
                    'group_name': self.group_name,
                    'proposer_id': self.proposer_id,
                    'proposer_name': self.proposer_name,
                    'status': self.status,
                    'votes_for': self.votes_for,
                    'votes_against': self.votes_against,
                    'decided_at': self.decided_at,
                    'created_at': self.created_at,
                    'votes': self.votes
                }
            
            @property
            def total_votes(self) -> int:
                """获取总投票数"""
                return self.votes_for + self.votes_against
            
            @property
            def pass_rate(self) -> float:
                """获取通过率"""
                total = self.total_votes
                if total == 0:
                    return 0.0
                return (self.votes_for / total) * 100
            
            def __repr__(self):
                return f"Decision({self.decision_id}: {self.title})"
        
        
        class DecisionManager:
            """决策管理器"""
            
            _decision_counter = 0
            
            @staticmethod
            def generate_decision_id() -> str:
                """生成决策唯一标识"""
                DecisionManager._decision_counter += 1
                return f"DEC-{datetime.now().strftime('%Y%m%d')}-{DecisionManager._decision_counter:03d}"
            
            @staticmethod
            def create(title: str, description: str, proposer_id: int,
                       group_id: Optional[int] = None) -> Optional[Decision]:
                """创建决策提议"""
                decision_id = DecisionManager.generate_decision_id()
                
                try:
                    db_id = db.insert(
                        """INSERT INTO decisions (decision_id, title, description, group_id, proposer_id,
                            status, votes_for, votes_against, created_at)
                           VALUES (?, ?, ?, ?, ?, 'proposed', 0, 0, ?)""",
                        (decision_id, title, description, group_id, proposer_id, datetime.now().isoformat())
                    )
                    
                    # 发送决策提议消息
                    proposer = AgentManager.get_by_id(proposer_id)
                    if proposer:
                        content = f"📊 新决策提议\n\n**{title}**\n{description}\n\n请投票: for/against/abstain\n决策ID: {decision_id}"
                        MessageManager.send_message(
                            from_agent_id=proposer_id,
                            content=content,
                            group_id=group_id,
                            msg_type="decision"
                        )
                    
                    return DecisionManager.get_by_id(db_id)
                except Exception as e:
                    print(f"创建决策提议失败: {e}")
                    return None
            
            @staticmethod
            def get_by_id(decision_db_id: int) -> Optional[Decision]:
                """通过 ID 获取决策"""
                row = db.fetch_one(
                    """SELECT d.*, 
                              a.name as proposer_name,
                              g.name as group_name
                       FROM decisions d
                       LEFT JOIN agents a ON d.proposer_id = a.id
                       LEFT JOIN groups g ON d.group_id = g.id
                       WHERE d.id = ?""",
                    (decision_db_id,)
                )
                if row:
                    decision = Decision(**row)
                    decision.proposer_name = row.get('proposer_name')
                    decision.group_name = row.get('group_name')
                    decision.votes = DecisionManager.get_votes(decision_db_id)
                    return decision
                return None
            
            @staticmethod
            def get_by_decision_id(decision_id: str) -> Optional[Decision]:
                """通过决策标识获取决策"""
                row = db.fetch_one(
                    """SELECT d.*, 
                              a.name as proposer_name,
                              g.name as group_name
                       FROM decisions d
                       LEFT JOIN agents a ON d.proposer_id = a.id
                       LEFT JOIN groups g ON d.group_id = g.id
                       WHERE d.decision_id = ?""",
                    (decision_id,)
                )
                if row:
                    decision = Decision(**row)
                    decision.proposer_name = row.get('proposer_name')
                    decision.group_name = row.get('group_name')
                    decision.votes = DecisionManager.get_votes(row['id'])
                    return decision
                return None
            
            @staticmethod
            def get_all(status: Optional[str] = None, group_id: Optional[int] = None) -> List[Decision]:
                """获取所有决策提议"""
                query = """SELECT d.*, 
                                  a.name as proposer_name,
                                  g.name as group_name
                           FROM decisions d
                           LEFT JOIN agents a ON d.proposer_id = a.id
                           LEFT JOIN groups g ON d.group_id = g.id"""
                params = []
                conditions = []
                
                if status:
                    conditions.append("d.status = ?")
                    params.append(status)
                if group_id:
                    conditions.append("d.group_id = ?")
                    params.append(group_id)
                
                if conditions:
                    query += " WHERE " + " AND ".join(conditions)
                
                query += " ORDER BY d.created_at DESC"
                
                rows = db.fetch_all(query, tuple(params))
                decisions = []
                for row in rows:
                    decision = Decision(**row)
                    decision.proposer_name = row.get('proposer_name')
                    decision.group_name = row.get('group_name')
                    decision.votes = DecisionManager.get_votes(row['id'])
                    decisions.append(decision)
                return decisions
            
            @staticmethod
            def vote(decision_db_id: int, agent_id: int, vote: str, comment: str = "") -> bool:
                """投票"""
                valid_votes = ['for', 'against', 'abstain']
                if vote not in valid_votes:
                    print(f"无效的投票选项: {vote}. 请使用 for/against/abstain")
                    return False
                
                decision = DecisionManager.get_by_id(decision_db_id)
                if not decision:
                    print("决策不存在")
                    return False
                
                if decision.status not in ['proposed', 'discussing']:
                    print(f"决策已关闭,无法投票 (当前状态: {decision.status})")
                    return False
                
                # 检查是否已经投过票
                existing = db.fetch_one(
                    "SELECT id FROM decision_votes WHERE decision_id = ? AND agent_id = ?",
                    (decision_db_id, agent_id)
                )
                
                if existing:
                    # 更新投票
                    db.execute(
                        "UPDATE decision_votes SET vote = ?, comment = ? WHERE id = ?",
                        (vote, comment, existing['id'])
                    )
                else:
                    # 新增投票
                    db.execute(
                        """INSERT INTO decision_votes (decision_id, agent_id, vote, comment, created_at)
                           VALUES (?, ?, ?, ?, ?)""",
                        (decision_db_id, agent_id, vote, comment, datetime.now().isoformat())
                    )
                
                # 更新决策的投票计数
                if vote == 'for':
                    db.execute(
                        "UPDATE decisions SET votes_for = votes_for + 1 WHERE id = ?",
                        (decision_db_id,)
                    )
                elif vote == 'against':
                    db.execute(
                        "UPDATE decisions SET votes_against = votes_against + 1 WHERE id = ?",
                        (decision_db_id,)
                    )
                
                # 发送投票通知
                agent = AgentManager.get_by_id(agent_id)
                vote_text = {'for': '✅ 赞成', 'against': '❌ 反对', 'abstain': '⚪ 弃权'}.get(vote, vote)
                
                content = f"🗳️ {agent.name if agent else 'Agent'} 投票: {vote_text}\n决策: {decision.title}"
                if comment:
                    content += f"\n意见: {comment}"
                
                MessageManager.send_message(
                    from_agent_id=agent_id,
                    content=content,
                    group_id=decision.group_id,
                    msg_type="chat"
                )
                
                return True
            
            @staticmethod
            def update_status(decision_db_id: int, new_status: str, updater_id: int) -> bool:
                """更新决策状态"""
                valid_status = ['proposed', 'discussing', 'approved', 'rejected', 'implemented']
                if new_status not in valid_status:
                    print(f"无效的状态: {new_status}")
                    return False
                
                decision = DecisionManager.get_by_id(decision_db_id)
                if not decision:
                    return False
                
                decided_at = datetime.now().isoformat() if new_status in ['approved', 'rejected'] else None
                
                affected = db.execute(
                    "UPDATE decisions SET status = ?, decided_at = ? WHERE id = ?",
                    (new_status, decided_at, decision_db_id)
                )
                
                if affected > 0:
                    status_text = {
                        'proposed': '提议中',
                        'discussing': '讨论中',
                        'approved': '已通过',
                        'rejected': '已否决',
                        'implemented': '已实施'
                    }.get(new_status, new_status)
                    
                    updater = AgentManager.get_by_id(updater_id)
                    content = f"📊 决策状态更新\n\n**{decision.title}**\n新状态: {status_text}"
                    
                    MessageManager.send_message(
                        from_agent_id=updater_id,
                        content=content,
                        group_id=decision.group_id,
                        msg_type="decision"
                    )
                    
                    return True
                return False
            
            @staticmethod
            def get_votes(decision_db_id: int) -> List[Dict]:
                """获取决策的所有投票"""
                rows = db.fetch_all(
                    """SELECT dv.*, a.name as agent_name
                       FROM decision_votes dv
                       JOIN agents a ON dv.agent_id = a.id
                       WHERE dv.decision_id = ?
                       ORDER BY dv.created_at""",
                    (decision_db_id,)
                )
                return [dict(row) for row in rows]
            
            @staticmethod
            def has_voted(decision_db_id: int, agent_id: int) -> bool:
                """检查 Agent 是否已经投票"""
                result = db.fetch_one(
                    "SELECT 1 FROM decision_votes WHERE decision_id = ? AND agent_id = ?",
                    (decision_db_id, agent_id)
                )
                return result is not None
            
            @staticmethod
            def delete(decision_db_id: int) -> bool:
                """删除决策"""
                affected = db.execute("DELETE FROM decisions WHERE id = ?", (decision_db_id,))
                return affected > 0
            
            @staticmethod
            def format_decision_for_display(decision: Decision, show_votes: bool = False) -> str:
                """格式化决策用于显示"""
                status_emoji = {
                    'proposed': '📝',
                    'discussing': '💬',
                    'approved': '✅',
                    'rejected': '❌',
                    'implemented': '🚀'
                }.get(decision.status, '⚪')
                
                lines = [
                    f"{status_emoji} [{decision.decision_id}] {decision.title}",
                    f"   提案人: {decision.proposer_name} | 状态: {decision.status}",
                    f"   投票: ✅ {decision.votes_for} 票 | ❌ {decision.votes_against} 票 | 通过率: {decision.pass_rate:.1f}%"
                ]
                
                if decision.description:
                    lines.append(f"   描述: {decision.description[:60]}{'...' if len(decision.description) > 60 else ''}")
                
                if show_votes and decision.votes:
                    lines.append("   投票详情:")
                    for v in decision.votes:
                        vote_emoji = {'for': '✅', 'against': '❌', 'abstain': '⚪'}.get(v['vote'], '⚪')
                        lines.append(f"     {vote_emoji} {v['agent_name']}: {v['vote']}")
                
                return "\n".join(lines)
        
      • group_manager.py 8 KB
        #!/usr/bin/env python3
        """
        Agent 群聊协作系统 - 群组管理模块
        负责群组的创建、成员管理等
        """
        
        from datetime import datetime
        from typing import Optional, List, Dict, Any
        import sys
        import os
        sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
        
        try:
            from database import db
            from agent_manager import AgentManager, Agent
        except ImportError:
            from .database import db
            from .agent_manager import AgentManager, Agent
        
        
        class Group:
            """群组类"""
            
            def __init__(self, id: int = None, group_id: int = None, name: str = "", description: str = "",
                         owner_id: Optional[int] = None, created_at: str = "", **kwargs):
                self.id = id if id is not None else group_id
                self.name = name
                self.description = description
                self.owner_id = owner_id
                self.created_at = created_at
                
                # 额外字段
                self.owner_name: Optional[str] = kwargs.get('owner_name')
                self.members: List[Agent] = []
            
            def to_dict(self) -> Dict[str, Any]:
                return {
                    'id': self.id,
                    'name': self.name,
                    'description': self.description,
                    'owner_id': self.owner_id,
                    'owner_name': self.owner_name,
                    'created_at': self.created_at,
                    'member_count': len(self.members),
                    'members': [m.to_dict() for m in self.members]
                }
            
            def __repr__(self):
                return f"Group({self.name}, members={len(self.members)})"
        
        
        class GroupManager:
            """群组管理器"""
            
            @staticmethod
            def create(name: str, owner_id: int, description: str = "") -> Optional[Group]:
                """创建新群组"""
                try:
                    group_id = db.insert(
                        "INSERT INTO groups (name, description, owner_id, created_at) VALUES (?, ?, ?, ?)",
                        (name, description, owner_id, datetime.now().isoformat())
                    )
                    # 自动将创建者加入群组
                    GroupManager.add_member(group_id, owner_id)
                    return GroupManager.get_by_id(group_id)
                except Exception as e:
                    print(f"创建群组失败: {e}")
                    return None
            
            @staticmethod
            def get_by_id(group_id: int) -> Optional[Group]:
                """通过 ID 获取群组"""
                row = db.fetch_one(
                    """SELECT g.*, a.name as owner_name 
                       FROM groups g 
                       LEFT JOIN agents a ON g.owner_id = a.id 
                       WHERE g.id = ?""",
                    (group_id,)
                )
                if row:
                    group = Group(**row)
                    group.owner_name = row.get('owner_name')
                    group.members = GroupManager.get_members(group_id)
                    return group
                return None
            
            @staticmethod
            def get_by_name(name: str) -> Optional[Group]:
                """通过名称获取群组"""
                row = db.fetch_one(
                    """SELECT g.*, a.name as owner_name 
                       FROM groups g 
                       LEFT JOIN agents a ON g.owner_id = a.id 
                       WHERE g.name = ?""",
                    (name,)
                )
                if row:
                    group = Group(**row)
                    group.owner_name = row.get('owner_name')
                    group.members = GroupManager.get_members(row['id'])
                    return group
                return None
            
            @staticmethod
            def get_all() -> List[Group]:
                """获取所有群组"""
                rows = db.fetch_all(
                    """SELECT g.*, a.name as owner_name 
                       FROM groups g 
                       LEFT JOIN agents a ON g.owner_id = a.id
                       ORDER BY g.created_at DESC"""
                )
                groups = []
                for row in rows:
                    group = Group(**row)
                    group.owner_name = row.get('owner_name')
                    group.members = GroupManager.get_members(row['id'])
                    groups.append(group)
                return groups
            
            @staticmethod
            def get_agent_groups(agent_id: int) -> List[Group]:
                """获取 Agent 加入的所有群组"""
                rows = db.fetch_all(
                    """SELECT g.*, a.name as owner_name 
                       FROM groups g 
                       JOIN group_members gm ON g.id = gm.group_id
                       LEFT JOIN agents a ON g.owner_id = a.id
                       WHERE gm.agent_id = ?
                       ORDER BY g.created_at DESC""",
                    (agent_id,)
                )
                groups = []
                for row in rows:
                    group = Group(**row)
                    group.owner_name = row.get('owner_name')
                    group.members = GroupManager.get_members(row['id'])
                    groups.append(group)
                return groups
            
            @staticmethod
            def add_member(group_id: int, agent_id: int) -> bool:
                """添加群组成员"""
                try:
                    db.execute(
                        "INSERT INTO group_members (group_id, agent_id, joined_at) VALUES (?, ?, ?)",
                        (group_id, agent_id, datetime.now().isoformat())
                    )
                    return True
                except Exception as e:
                    print(f"添加成员失败: {e}")
                    return False
            
            @staticmethod
            def remove_member(group_id: int, agent_id: int) -> bool:
                """移除群组成员"""
                affected = db.execute(
                    "DELETE FROM group_members WHERE group_id = ? AND agent_id = ?",
                    (group_id, agent_id)
                )
                return affected > 0
            
            @staticmethod
            def get_members(group_id: int) -> List[Agent]:
                """获取群组成员列表"""
                rows = db.fetch_all(
                    """SELECT a.* FROM agents a
                       JOIN group_members gm ON a.id = gm.agent_id
                       WHERE gm.group_id = ?
                       ORDER BY gm.joined_at""",
                    (group_id,)
                )
                return [Agent(**row) for row in rows]
            
            @staticmethod
            def is_member(group_id: int, agent_id: int) -> bool:
                """检查 Agent 是否在群组中"""
                result = db.fetch_one(
                    "SELECT 1 FROM group_members WHERE group_id = ? AND agent_id = ?",
                    (group_id, agent_id)
                )
                return result is not None
            
            @staticmethod
            def update(group_id: int, name: str = None, description: str = None) -> bool:
                """更新群组信息"""
                updates = []
                params = []
                
                if name:
                    updates.append("name = ?")
                    params.append(name)
                if description:
                    updates.append("description = ?")
                    params.append(description)
                
                if not updates:
                    return False
                
                params.append(group_id)
                affected = db.execute(
                    f"UPDATE groups SET {', '.join(updates)} WHERE id = ?",
                    tuple(params)
                )
                return affected > 0
            
            @staticmethod
            def delete(group_id: int) -> bool:
                """删除群组(同时删除所有相关记录)"""
                # 数据库外键会处理相关记录的级联删除
                affected = db.execute("DELETE FROM groups WHERE id = ?", (group_id,))
                return affected > 0
            
            @staticmethod
            def transfer_ownership(group_id: int, new_owner_id: int) -> bool:
                """转移群组所有权"""
                # 确保新群主在群组中
                if not GroupManager.is_member(group_id, new_owner_id):
                    GroupManager.add_member(group_id, new_owner_id)
                
                affected = db.execute(
                    "UPDATE groups SET owner_id = ? WHERE id = ?",
                    (new_owner_id, group_id)
                )
                return affected > 0
            
            @staticmethod
            def get_member_count(group_id: int) -> int:
                """获取群组成员数量"""
                result = db.fetch_one(
                    "SELECT COUNT(*) as count FROM group_members WHERE group_id = ?",
                    (group_id,)
                )
                return result['count'] if result else 0
            
            @staticmethod
            def list_online_members(group_id: int) -> List[Agent]:
                """获取群组在线成员"""
                rows = db.fetch_all(
                    """SELECT a.* FROM agents a
                       JOIN group_members gm ON a.id = gm.agent_id
                       WHERE gm.group_id = ? AND a.status = 'online'
                       ORDER BY a.last_active DESC""",
                    (group_id,)
                )
                return [Agent(**row) for row in rows]
        
      • message_manager.py 11.7 KB
        #!/usr/bin/env python3
        """
        Agent 群聊协作系统 - 消息核心模块
        负责消息的创建、发送、@提及处理等
        """
        
        import re
        import json
        from datetime import datetime
        from typing import Optional, List, Dict, Any, Tuple
        from enum import Enum
        import sys
        import os
        sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
        
        try:
            from database import db
            from agent_manager import AgentManager, Agent
        except ImportError:
            from .database import db
            from .agent_manager import AgentManager, Agent
        
        
        class MessageType(Enum):
            """消息类型枚举"""
            CHAT = "chat"           # 普通聊天
            MENTION = "mention"     # @提及
            TASK_ASSIGN = "task_assign"    # 任务指派
            TASK_COMPLETE = "task_complete"  # 任务完成
            DECISION = "decision"   # 决策提议
            SYSTEM = "system"       # 系统消息
            REPLY = "reply"         # 回复消息
        
        
        class Message:
            """消息类"""
            
            def __init__(self, id: int = None, msg_id: int = None, group_id: Optional[int] = None,
                         from_agent_id: int = None, to_agent_id: Optional[int] = None,
                         content: str = "", msg_type: str = "", type: str = "",
                         reply_to: Optional[int] = None, created_at: str = "",
                         **kwargs):
                self.id = id if id is not None else msg_id
                self.group_id = group_id
                self.from_agent_id = from_agent_id
                self.to_agent_id = to_agent_id
                self.content = content
                self.type = msg_type if msg_type else type
                self.reply_to = reply_to
                self.created_at = created_at
                
                # 额外字段(通过 JOIN 查询填充)
                self.from_agent_name: Optional[str] = kwargs.get('from_agent_name')
                self.to_agent_name: Optional[str] = kwargs.get('to_agent_name')
                self.group_name: Optional[str] = kwargs.get('group_name')
            
            def to_dict(self) -> Dict[str, Any]:
                return {
                    'id': self.id,
                    'group_id': self.group_id,
                    'group_name': self.group_name,
                    'from_agent_id': self.from_agent_id,
                    'from_agent_name': self.from_agent_name,
                    'to_agent_id': self.to_agent_id,
                    'to_agent_name': self.to_agent_name,
                    'content': self.content,
                    'type': self.type,
                    'reply_to': self.reply_to,
                    'created_at': self.created_at
                }
            
            def __repr__(self):
                return f"Message({self.id}: {self.from_agent_name} -> {self.to_agent_name or 'all'}: {self.content[:30]}...)"
        
        
        class MessageManager:
            """消息管理器"""
            
            # 用于匹配 @AgentName 的正则表达式
            MENTION_PATTERN = re.compile(r'@([^\s@]+)')
            
            @staticmethod
            def send_message(from_agent_id: int, content: str, group_id: Optional[int] = None,
                             to_agent_id: Optional[int] = None, msg_type: str = "chat",
                             reply_to: Optional[int] = None) -> Optional[Message]:
                """发送消息"""
                # 检测消息中的 @提及
                mentions = MessageManager.detect_mentions(content)
                
                # 如果消息包含 @提及且没有指定接收者,标记为 mention 类型
                if mentions and msg_type == "chat":
                    msg_type = "mention"
                
                # 插入消息
                msg_id = db.insert(
                    """INSERT INTO messages (group_id, from_agent_id, to_agent_id, content, type, reply_to, created_at)
                       VALUES (?, ?, ?, ?, ?, ?, ?)""",
                    (group_id, from_agent_id, to_agent_id, content, msg_type, reply_to, datetime.now().isoformat())
                )
                
                # 为 @提及的 Agent 创建收件箱通知
                for mentioned_agent in mentions:
                    MessageManager.create_inbox_notification(mentioned_agent.id, msg_id)
                
                # 如果是私信(指定了接收者),也为接收者创建通知
                if to_agent_id:
                    MessageManager.create_inbox_notification(to_agent_id, msg_id)
                
                return MessageManager.get_by_id(msg_id)
            
            @staticmethod
            def detect_mentions(content: str) -> List[Agent]:
                """检测消息中的 @提及"""
                mentioned_agents = []
                matches = MessageManager.MENTION_PATTERN.findall(content)
                
                for name in matches:
                    agent = AgentManager.get_by_name(name)
                    if agent:
                        mentioned_agents.append(agent)
                
                return mentioned_agents
            
            @staticmethod
            def create_inbox_notification(agent_id: int, message_id: int):
                """为 Agent 创建收件箱通知"""
                db.execute(
                    "INSERT INTO agent_inbox (agent_id, message_id, is_read, notified_at) VALUES (?, ?, FALSE, ?)",
                    (agent_id, message_id, datetime.now().isoformat())
                )
            
            @staticmethod
            def get_by_id(msg_id: int) -> Optional[Message]:
                """通过 ID 获取消息"""
                row = db.fetch_one(
                    """SELECT m.*, 
                              fa.name as from_agent_name, 
                              ta.name as to_agent_name,
                              g.name as group_name
                       FROM messages m
                       LEFT JOIN agents fa ON m.from_agent_id = fa.id
                       LEFT JOIN agents ta ON m.to_agent_id = ta.id
                       LEFT JOIN groups g ON m.group_id = g.id
                       WHERE m.id = ?""",
                    (msg_id,)
                )
                if row:
                    msg = Message(**row)
                    return msg
                return None
            
            @staticmethod
            def get_group_messages(group_id: int, limit: int = 50, offset: int = 0) -> List[Message]:
                """获取群组消息历史"""
                rows = db.fetch_all(
                    """SELECT m.*, 
                              fa.name as from_agent_name, 
                              ta.name as to_agent_name,
                              g.name as group_name
                       FROM messages m
                       LEFT JOIN agents fa ON m.from_agent_id = fa.id
                       LEFT JOIN agents ta ON m.to_agent_id = ta.id
                       LEFT JOIN groups g ON m.group_id = g.id
                       WHERE m.group_id = ?
                       ORDER BY m.created_at DESC
                       LIMIT ? OFFSET ?""",
                    (group_id, limit, offset)
                )
                return [MessageManager._row_to_message(row) for row in rows]
            
            @staticmethod
            def get_agent_inbox(agent_id: int, only_unread: bool = False) -> List[Dict[str, Any]]:
                """获取 Agent 的收件箱"""
                query = """SELECT ai.*, m.content, m.type, m.created_at as msg_created_at,
                                  fa.name as from_agent_name, g.name as group_name
                           FROM agent_inbox ai
                           JOIN messages m ON ai.message_id = m.id
                           LEFT JOIN agents fa ON m.from_agent_id = fa.id
                           LEFT JOIN groups g ON m.group_id = g.id
                           WHERE ai.agent_id = ?"""
                
                if only_unread:
                    query += " AND ai.is_read = FALSE"
                
                query += " ORDER BY m.created_at DESC"
                
                return db.fetch_all(query, (agent_id,))
            
            @staticmethod
            def mark_as_read(agent_id: int, message_id: int) -> bool:
                """标记消息为已读"""
                affected = db.execute(
                    "UPDATE agent_inbox SET is_read = TRUE, read_at = ? WHERE agent_id = ? AND message_id = ?",
                    (datetime.now().isoformat(), agent_id, message_id)
                )
                return affected > 0
            
            @staticmethod
            def mark_all_as_read(agent_id: int) -> int:
                """标记所有消息为已读"""
                return db.execute(
                    "UPDATE agent_inbox SET is_read = TRUE, read_at = ? WHERE agent_id = ? AND is_read = FALSE",
                    (datetime.now().isoformat(), agent_id)
                )
            
            @staticmethod
            def get_unread_count(agent_id: int) -> int:
                """获取未读消息数量"""
                result = db.fetch_one(
                    "SELECT COUNT(*) as count FROM agent_inbox WHERE agent_id = ? AND is_read = FALSE",
                    (agent_id,)
                )
                return result['count'] if result else 0
            
            @staticmethod
            def search_messages(keyword: str, group_id: Optional[int] = None,
                                from_agent_id: Optional[int] = None) -> List[Message]:
                """搜索消息"""
                query = """SELECT m.*, 
                                  fa.name as from_agent_name, 
                                  ta.name as to_agent_name,
                                  g.name as group_name
                           FROM messages m
                           LEFT JOIN agents fa ON m.from_agent_id = fa.id
                           LEFT JOIN agents ta ON m.to_agent_id = ta.id
                           LEFT JOIN groups g ON m.group_id = g.id
                           WHERE m.content LIKE ?"""
                params = [f"%{keyword}%"]
                
                if group_id:
                    query += " AND m.group_id = ?"
                    params.append(group_id)
                
                if from_agent_id:
                    query += " AND m.from_agent_id = ?"
                    params.append(from_agent_id)
                
                query += " ORDER BY m.created_at DESC LIMIT 100"
                
                rows = db.fetch_all(query, tuple(params))
                return [MessageManager._row_to_message(row) for row in rows]
            
            @staticmethod
            def _row_to_message(row: Dict) -> Message:
                """将数据库行转换为 Message 对象"""
                msg = Message(
                    msg_id=row['id'],
                    group_id=row.get('group_id'),
                    from_agent_id=row['from_agent_id'],
                    to_agent_id=row.get('to_agent_id'),
                    content=row['content'],
                    msg_type=row['type'],
                    reply_to=row.get('reply_to'),
                    created_at=row['created_at']
                )
                msg.from_agent_name = row.get('from_agent_name')
                msg.to_agent_name = row.get('to_agent_name')
                msg.group_name = row.get('group_name')
                return msg
            
            @staticmethod
            def format_message_for_display(msg: Message) -> str:
                """格式化消息用于显示"""
                time_str = msg.created_at[11:19] if len(msg.created_at) > 19 else msg.created_at
                from_name = msg.from_agent_name or f"Agent-{msg.from_agent_id}"
                
                if msg.group_name:
                    location = f"[{msg.group_name}]"
                else:
                    location = "[私信]"
                
                if msg.to_agent_name:
                    target = f" @{msg.to_agent_name}"
                else:
                    target = ""
                
                return f"[{time_str}] {location} {from_name}{target}: {msg.content}"
        
        
        class MessageFormatter:
            """消息格式化工具"""
            
            @staticmethod
            def chat(content: str) -> str:
                """普通聊天消息"""
                return content
            
            @staticmethod
            def mention(content: str, agent_names: List[str]) -> str:
                """@提及消息"""
                mentions = " ".join([f"@{name}" for name in agent_names])
                return f"{mentions} {content}"
            
            @staticmethod
            def task_assign(assignee: str, task_title: str, description: str = "", 
                            priority: str = "normal", due_date: str = "") -> str:
                """任务指派消息"""
                lines = [f"@{assignee} 新任务指派", f"标题: {task_title}"]
                if description:
                    lines.append(f"描述: {description}")
                lines.append(f"优先级: {priority}")
                if due_date:
                    lines.append(f"截止日期: {due_date}")
                return "\n".join(lines)
            
            @staticmethod
            def task_complete(task_id: str, result: str = "") -> str:
                """任务完成消息"""
                lines = [f"任务 {task_id} 已完成"]
                if result:
                    lines.append(f"结果: {result}")
                return "\n".join(lines)
            
            @staticmethod
            def decision_proposal(title: str, description: str, options: List[str] = None) -> str:
                """决策提议消息"""
                lines = [f"【决策提议】{title}", f"描述: {description}"]
                if options:
                    lines.append("选项:")
                    for i, opt in enumerate(options, 1):
                        lines.append(f"  {i}. {opt}")
                return "\n".join(lines)
        
      • task_manager.py 12.8 KB
        #!/usr/bin/env python3
        """
        Agent 群聊协作系统 - 任务管理模块
        负责任务的创建、指派、状态更新、评论等
        """
        
        from datetime import datetime
        from typing import Optional, List, Dict, Any
        import sys
        import os
        sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
        
        try:
            from database import db
            from agent_manager import AgentManager
            from message_manager import MessageManager
        except ImportError:
            from .database import db
            from .agent_manager import AgentManager
            from .message_manager import MessageManager
        
        
        class TaskStatus:
            """任务状态常量"""
            PENDING = "pending"
            IN_PROGRESS = "in_progress"
            COMPLETED = "completed"
            CANCELLED = "cancelled"
        
        
        class TaskPriority:
            """任务优先级常量"""
            LOW = "low"
            NORMAL = "normal"
            HIGH = "high"
            URGENT = "urgent"
        
        
        class Task:
            """任务类"""
            
            def __init__(self, id: int = None, task_db_id: int = None, task_id: str = "", title: str = "",
                         description: str = "", assigner_id: int = None, assignee_id: int = None,
                         group_id: Optional[int] = None, status: str = "pending", priority: str = "normal",
                         due_date: Optional[str] = None, completed_at: Optional[str] = None,
                         created_at: str = "", **kwargs):
                self.id = id if id is not None else task_db_id
                self.task_id = task_id
                self.title = title
                self.description = description
                self.assigner_id = assigner_id
                self.assignee_id = assignee_id
                self.group_id = group_id
                self.status = status
                self.priority = priority
                self.due_date = due_date
                self.completed_at = completed_at
                self.created_at = created_at
                
                # 额外字段
                self.assigner_name: Optional[str] = kwargs.get('assigner_name')
                self.assignee_name: Optional[str] = kwargs.get('assignee_name')
                self.group_name: Optional[str] = kwargs.get('group_name')
                self.comments: List[Dict] = []
            
            def to_dict(self) -> Dict[str, Any]:
                return {
                    'id': self.id,
                    'task_id': self.task_id,
                    'title': self.title,
                    'description': self.description,
                    'assigner_id': self.assigner_id,
                    'assigner_name': self.assigner_name,
                    'assignee_id': self.assignee_id,
                    'assignee_name': self.assignee_name,
                    'group_id': self.group_id,
                    'group_name': self.group_name,
                    'status': self.status,
                    'priority': self.priority,
                    'due_date': self.due_date,
                    'completed_at': self.completed_at,
                    'created_at': self.created_at,
                    'comments': self.comments
                }
            
            def __repr__(self):
                return f"Task({self.task_id}: {self.title} -> {self.assignee_name})"
        
        
        class TaskManager:
            """任务管理器"""
            
            _task_counter = 0
            
            @staticmethod
            def generate_task_id() -> str:
                """生成任务唯一标识"""
                TaskManager._task_counter += 1
                return f"TASK-{datetime.now().strftime('%Y%m%d')}-{TaskManager._task_counter:03d}"
            
            @staticmethod
            def create(title: str, assigner_id: int, assignee_id: int,
                       description: str = "", group_id: Optional[int] = None,
                       priority: str = "normal", due_date: Optional[str] = None) -> Optional[Task]:
                """创建新任务"""
                task_id = TaskManager.generate_task_id()
                
                try:
                    db_id = db.insert(
                        """INSERT INTO tasks (task_id, title, description, assigner_id, assignee_id,
                            group_id, status, priority, due_date, created_at)
                           VALUES (?, ?, ?, ?, ?, ?, 'pending', ?, ?, ?)""",
                        (task_id, title, description, assigner_id, assignee_id,
                         group_id, priority, due_date, datetime.now().isoformat())
                    )
                    
                    # 发送任务指派消息
                    assigner = AgentManager.get_by_id(assigner_id)
                    assignee = AgentManager.get_by_id(assignee_id)
                    
                    if assigner and assignee:
                        content = f"📝 新任务指派给 @{assignee.name}\n\n**{title}**\n{description}\n\n优先级: {priority}"
                        if due_date:
                            content += f" | 截止: {due_date}"
                        content += f" | 任务ID: {task_id}"
                        
                        MessageManager.send_message(
                            from_agent_id=assigner_id,
                            content=content,
                            group_id=group_id,
                            to_agent_id=assignee_id,
                            msg_type="task_assign"
                        )
                    
                    return TaskManager.get_by_id(db_id)
                except Exception as e:
                    print(f"创建任务失败: {e}")
                    return None
            
            @staticmethod
            def get_by_id(task_db_id: int) -> Optional[Task]:
                """通过 ID 获取任务"""
                row = db.fetch_one(
                    """SELECT t.*, 
                              a1.name as assigner_name, 
                              a2.name as assignee_name,
                              g.name as group_name
                       FROM tasks t
                       LEFT JOIN agents a1 ON t.assigner_id = a1.id
                       LEFT JOIN agents a2 ON t.assignee_id = a2.id
                       LEFT JOIN groups g ON t.group_id = g.id
                       WHERE t.id = ?""",
                    (task_db_id,)
                )
                if row:
                    task = Task(**row)
                    task.assigner_name = row.get('assigner_name')
                    task.assignee_name = row.get('assignee_name')
                    task.group_name = row.get('group_name')
                    task.comments = TaskManager.get_comments(task_db_id)
                    return task
                return None
            
            @staticmethod
            def get_by_task_id(task_id: str) -> Optional[Task]:
                """通过任务标识获取任务"""
                row = db.fetch_one(
                    """SELECT t.*, 
                              a1.name as assigner_name, 
                              a2.name as assignee_name,
                              g.name as group_name
                       FROM tasks t
                       LEFT JOIN agents a1 ON t.assigner_id = a1.id
                       LEFT JOIN agents a2 ON t.assignee_id = a2.id
                       LEFT JOIN groups g ON t.group_id = g.id
                       WHERE t.task_id = ?""",
                    (task_id,)
                )
                if row:
                    task = Task(**row)
                    task.assigner_name = row.get('assigner_name')
                    task.assignee_name = row.get('assignee_name')
                    task.group_name = row.get('group_name')
                    task.comments = TaskManager.get_comments(row['id'])
                    return task
                return None
            
            @staticmethod
            def get_all(status: Optional[str] = None, assignee_id: Optional[int] = None) -> List[Task]:
                """获取所有任务"""
                query = """SELECT t.*, 
                                  a1.name as assigner_name, 
                                  a2.name as assignee_name,
                                  g.name as group_name
                           FROM tasks t
                           LEFT JOIN agents a1 ON t.assigner_id = a1.id
                           LEFT JOIN agents a2 ON t.assignee_id = a2.id
                           LEFT JOIN groups g ON t.group_id = g.id"""
                params = []
                conditions = []
                
                if status:
                    conditions.append("t.status = ?")
                    params.append(status)
                if assignee_id:
                    conditions.append("t.assignee_id = ?")
                    params.append(assignee_id)
                
                if conditions:
                    query += " WHERE " + " AND ".join(conditions)
                
                query += " ORDER BY t.created_at DESC"
                
                rows = db.fetch_all(query, tuple(params))
                tasks = []
                for row in rows:
                    task = Task(**row)
                    task.assigner_name = row.get('assigner_name')
                    task.assignee_name = row.get('assignee_name')
                    task.group_name = row.get('group_name')
                    task.comments = TaskManager.get_comments(row['id'])
                    tasks.append(task)
                return tasks
            
            @staticmethod
            def update_status(task_db_id: int, new_status: str, updater_id: int, comment: str = "") -> bool:
                """更新任务状态"""
                valid_status = ['pending', 'in_progress', 'completed', 'cancelled']
                if new_status not in valid_status:
                    print(f"无效的状态: {new_status}")
                    return False
                
                task = TaskManager.get_by_id(task_db_id)
                if not task:
                    return False
                
                completed_at = datetime.now().isoformat() if new_status == 'completed' else None
                
                affected = db.execute(
                    "UPDATE tasks SET status = ?, completed_at = ? WHERE id = ?",
                    (new_status, completed_at, task_db_id)
                )
                
                if affected > 0:
                    # 添加评论记录状态变更
                    status_text = {
                        'pending': '待处理',
                        'in_progress': '进行中',
                        'completed': '已完成',
                        'cancelled': '已取消'
                    }.get(new_status, new_status)
                    
                    updater = AgentManager.get_by_id(updater_id)
                    updater_name = updater.name if updater else f"Agent-{updater_id}"
                    
                    comment_text = f"状态变更为: {status_text}"
                    if comment:
                        comment_text += f" | 备注: {comment}"
                    
                    TaskManager.add_comment(task_db_id, updater_id, comment_text)
                    
                    # 发送状态变更通知
                    content = f"✅ 任务 {task.task_id} 状态更新\n\n**{task.title}**\n新状态: {status_text}"
                    if comment:
                        content += f"\n备注: {comment}"
                    
                    MessageManager.send_message(
                        from_agent_id=updater_id,
                        content=content,
                        group_id=task.group_id,
                        to_agent_id=task.assignee_id if updater_id != task.assignee_id else task.assigner_id,
                        msg_type="task_complete" if new_status == 'completed' else "chat"
                    )
                    
                    return True
                return False
            
            @staticmethod
            def start_task(task_db_id: int, agent_id: int) -> bool:
                """开始任务(状态变为 in_progress)"""
                return TaskManager.update_status(task_db_id, 'in_progress', agent_id, "开始处理任务")
            
            @staticmethod
            def complete_task(task_db_id: int, agent_id: int, result: str = "") -> bool:
                """完成任务"""
                return TaskManager.update_status(task_db_id, 'completed', agent_id, result)
            
            @staticmethod
            def add_comment(task_db_id: int, agent_id: int, comment: str) -> bool:
                """添加任务评论"""
                try:
                    db.execute(
                        "INSERT INTO task_comments (task_id, agent_id, comment, created_at) VALUES (?, ?, ?, ?)",
                        (task_db_id, agent_id, comment, datetime.now().isoformat())
                    )
                    return True
                except Exception as e:
                    print(f"添加评论失败: {e}")
                    return False
            
            @staticmethod
            def get_comments(task_db_id: int) -> List[Dict]:
                """获取任务评论"""
                rows = db.fetch_all(
                    """SELECT tc.*, a.name as agent_name
                       FROM task_comments tc
                       JOIN agents a ON tc.agent_id = a.id
                       WHERE tc.task_id = ?
                       ORDER BY tc.created_at""",
                    (task_db_id,)
                )
                return [dict(row) for row in rows]
            
            @staticmethod
            def delete(task_db_id: int) -> bool:
                """删除任务"""
                affected = db.execute("DELETE FROM tasks WHERE id = ?", (task_db_id,))
                return affected > 0
            
            @staticmethod
            def get_agent_tasks(agent_id: int, status: Optional[str] = None) -> List[Task]:
                """获取指定 Agent 的任务列表"""
                return TaskManager.get_all(status=status, assignee_id=agent_id)
            
            @staticmethod
            def format_task_for_display(task: Task) -> str:
                """格式化任务用于显示"""
                priority_emoji = {
                    'low': '🔵',
                    'normal': '🟡',
                    'high': '🟠',
                    'urgent': '🔴'
                }.get(task.priority, '⚪')
                
                status_emoji = {
                    'pending': '⏳',
                    'in_progress': '🔄',
                    'completed': '✅',
                    'cancelled': '❌'
                }.get(task.status, '⚪')
                
                lines = [
                    f"{status_emoji} {priority_emoji} [{task.task_id}] {task.title}",
                    f"   指派给: {task.assignee_name} | 来自: {task.assigner_name}",
                ]
                
                if task.description:
                    lines.append(f"   描述: {task.description[:50]}{'...' if len(task.description) > 50 else ''}")
                
                if task.due_date:
                    lines.append(f"   截止: {task.due_date}")
                
                if task.comments:
                    lines.append(f"   💬 {len(task.comments)} 条评论")
                
                return "\n".join(lines)
        
      • __init__.py 1.9 KB
        """
        Agent Network - Multi-Agent Group Chat Collaboration System
        
        A complete multi-agent collaboration platform with group chat, @mentions,
        task management, and decision voting.
        
        Example:
            >>> from agent_network import AgentManager, GroupManager, init_default_agents
            >>> from agent_network import get_coordinator
            >>> 
            >>> # Initialize
            >>> init_default_agents()
            >>> 
            >>> # Use coordinator
            >>> coord = get_coordinator()
            >>> coord.register_agent(1)
            >>> coord.send_message(1, "Hello team!", group_id=1)
        """
        
        __version__ = "1.0.0"
        __author__ = "Agent Network Team"
        
        # Core imports
        from .database import Database, db
        from .agent_manager import Agent, AgentManager, init_default_agents
        from .group_manager import Group, GroupManager
        from .message_manager import Message, MessageManager, MessageType, MessageFormatter
        from .task_manager import Task, TaskManager
        from .decision_manager import Decision, DecisionManager
        from .coordinator import Coordinator, get_coordinator, AgentSession
        
        __all__ = [
            # Version
            "__version__",
            
            # Database
            "Database",
            "db",
            
            # Agent
            "Agent",
            "AgentManager",
            "init_default_agents",
            
            # Group
            "Group",
            "GroupManager",
            
            # Message
            "Message",
            "MessageManager",
            "MessageType",
            "MessageFormatter",
            
            # Task
            "Task",
            "TaskManager",
            
            # Decision
            "Decision",
            "DecisionManager",
            
            # Coordinator
            "Coordinator",
            "get_coordinator",
            "AgentSession",
        ]
        
        # Constants
        DEFAULT_AGENTS = [
            ("老邢", "Manager", "Overall coordination and decision making"),
            ("小邢", "DevOps", "Development and operations"),
            ("小金", "Finance Analyst", "Financial market analysis"),
            ("小陈", "Trader", "Trading execution"),
            ("小影", "Designer", "Design and short video content"),
            ("小视频", "Video Producer", "Video production and editing"),
        ]
        
    • cli.py 20.5 KB
      #!/usr/bin/env python3
      """
      Agent 群聊协作系统 - 交互式 CLI 界面
      提供类似钉钉/飞书的群聊交互体验
      """
      
      import os
      import sys
      import time
      import readline
      from typing import Optional, List
      from datetime import datetime
      
      # 添加 src 到路径
      sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
      
      from src.database import db
      from src.agent_manager import AgentManager, Agent, init_default_agents
      from src.group_manager import GroupManager, Group
      from src.message_manager import MessageManager, Message, MessageFormatter
      from src.task_manager import TaskManager, Task
      from src.decision_manager import DecisionManager, Decision
      
      
      class Colors:
          """终端颜色"""
          RESET = '\033[0m'
          BOLD = '\033[1m'
          DIM = '\033[2m'
          RED = '\033[91m'
          GREEN = '\033[92m'
          YELLOW = '\033[93m'
          BLUE = '\033[94m'
          MAGENTA = '\033[95m'
          CYAN = '\033[96m'
          WHITE = '\033[97m'
      
      
      class AgentChatCLI:
          """Agent 群聊 CLI 界面"""
          
          def __init__(self):
              self.current_agent: Optional[Agent] = None
              self.current_group: Optional[Group] = None
              self.running = True
              
          def clear_screen(self):
              """清屏"""
              os.system('clear' if os.name == 'posix' else 'cls')
          
          def print_header(self, title: str):
              """打印标题"""
              print(f"\n{Colors.CYAN}{'='*60}{Colors.RESET}")
              print(f"{Colors.BOLD}{Colors.WHITE}{title.center(60)}{Colors.RESET}")
              print(f"{Colors.CYAN}{'='*60}{Colors.RESET}\n")
          
          def print_success(self, message: str):
              """打印成功消息"""
              print(f"{Colors.GREEN}✓ {message}{Colors.RESET}")
          
          def print_error(self, message: str):
              """打印错误消息"""
              print(f"{Colors.RED}✗ {message}{Colors.RESET}")
          
          def print_info(self, message: str):
              """打印信息"""
              print(f"{Colors.BLUE}ℹ {message}{Colors.RESET}")
          
          def print_warning(self, message: str):
              """打印警告"""
              print(f"{Colors.YELLOW}⚠ {message}{Colors.RESET}")
          
          def get_input(self, prompt: str) -> str:
              """获取用户输入"""
              try:
                  return input(f"{Colors.CYAN}{prompt}{Colors.RESET}").strip()
              except EOFError:
                  return ""
          
          def login_menu(self):
              """登录菜单"""
              self.clear_screen()
              self.print_header("🤖 Agent Network - 群聊协作系统")
              
              print(f"{Colors.DIM}初始化默认 Agent...{Colors.RESET}")
              init_default_agents()
              
              agents = AgentManager.get_all()
              
              print(f"\n{Colors.BOLD}可用 Agent 列表:{Colors.RESET}\n")
              for i, agent in enumerate(agents, 1):
                  status_color = Colors.GREEN if agent.status == 'online' else Colors.DIM
                  print(f"  {Colors.YELLOW}[{i}]{Colors.RESET} {status_color}{agent.name}{Colors.RESET} - {agent.role}")
              
              print(f"\n  {Colors.YELLOW}[0]{Colors.RESET} 退出系统")
              
              choice = self.get_input("\n请选择 Agent (输入编号): ")
              
              if choice == '0':
                  self.running = False
                  return
              
              try:
                  idx = int(choice) - 1
                  if 0 <= idx < len(agents):
                      self.current_agent = agents[idx]
                      AgentManager.go_online(self.current_agent.id)
                      self.current_agent.status = 'online'
                      self.print_success(f"欢迎, {self.current_agent.name}!")
                      time.sleep(1)
                  else:
                      self.print_error("无效的选择")
                      time.sleep(1)
              except ValueError:
                  self.print_error("请输入有效的数字")
                  time.sleep(1)
          
          def main_menu(self):
              """主菜单"""
              while self.running and self.current_agent:
                  self.clear_screen()
                  
                  # 获取未读消息数
                  unread_count = MessageManager.get_unread_count(self.current_agent.id)
                  unread_badge = f" [{Colors.RED}{unread_count} 未读{Colors.RESET}]" if unread_count > 0 else ""
                  
                  group_name = f" @{self.current_group.name}" if self.current_group else ""
                  self.print_header(f"🤖 {self.current_agent.name}{group_name}{unread_badge}")
                  
                  print(f"{Colors.BOLD}主菜单:{Colors.RESET}\n")
                  print(f"  {Colors.YELLOW}[1]{Colors.RESET} 进入群组")
                  print(f"  {Colors.YELLOW}[2]{Colors.RESET} 创建群组")
                  print(f"  {Colors.YELLOW}[3]{Colors.RESET} 查看任务")
                  print(f"  {Colors.YELLOW}[4]{Colors.RESET} 查看决策")
                  print(f"  {Colors.YELLOW}[5]{Colors.RESET} 查看收件箱{unread_badge}")
                  print(f"  {Colors.YELLOW}[6]{Colors.RESET} 切换 Agent")
                  print(f"  {Colors.YELLOW}[0]{Colors.RESET} 退出")
                  
                  choice = self.get_input("\n请选择操作: ")
                  
                  if choice == '1':
                      self.select_group()
                  elif choice == '2':
                      self.create_group()
                  elif choice == '3':
                      self.view_tasks()
                  elif choice == '4':
                      self.view_decisions()
                  elif choice == '5':
                      self.view_inbox()
                  elif choice == '6':
                      AgentManager.go_offline(self.current_agent.id)
                      self.current_agent = None
                      self.current_group = None
                      return
                  elif choice == '0':
                      self.logout()
                  else:
                      self.print_error("无效的选择")
                      time.sleep(1)
          
          def select_group(self):
              """选择群组"""
              groups = GroupManager.get_agent_groups(self.current_agent.id)
              
              if not groups:
                  self.print_warning("你还没有加入任何群组")
                  self.get_input("按回车继续...")
                  return
              
              self.clear_screen()
              self.print_header("📁 选择群组")
              
              print(f"{Colors.BOLD}你的群组:{Colors.RESET}\n")
              for i, group in enumerate(groups, 1):
                  member_count = len(group.members)
                  online_count = len([m for m in group.members if m.status == 'online'])
                  print(f"  {Colors.YELLOW}[{i}]{Colors.RESET} {group.name} ({online_count}/{member_count} 在线)")
                  if group.description:
                      print(f"      {Colors.DIM}{group.description}{Colors.RESET}")
              
              print(f"\n  {Colors.YELLOW}[0]{Colors.RESET} 返回")
              
              choice = self.get_input("\n请选择群组: ")
              
              if choice == '0':
                  return
              
              try:
                  idx = int(choice) - 1
                  if 0 <= idx < len(groups):
                      self.current_group = groups[idx]
                      self.enter_group_chat()
                  else:
                      self.print_error("无效的选择")
                      time.sleep(1)
              except ValueError:
                  self.print_error("请输入有效的数字")
                  time.sleep(1)
          
          def enter_group_chat(self):
              """进入群组聊天"""
              if not self.current_group:
                  return
              
              while self.running:
                  self.clear_screen()
                  
                  # 获取在线成员
                  online_members = GroupManager.list_online_members(self.current_group.id)
                  online_names = [m.name for m in online_members]
                  
                  header = f"💬 {self.current_group.name} ({len(online_members)} 人在线)"
                  self.print_header(header)
                  
                  # 显示最近消息
                  messages = MessageManager.get_group_messages(self.current_group.id, limit=20)
                  messages.reverse()  # 按时间正序显示
                  
                  if messages:
                      for msg in messages:
                          self.display_message(msg)
                  else:
                      print(f"{Colors.DIM}暂无消息,开始聊天吧!{Colors.RESET}")
                  
                  print(f"\n{Colors.CYAN}{'-'*60}{Colors.RESET}")
                  print(f"{Colors.DIM}在线: {', '.join(online_names) or '无'}{Colors.RESET}")
                  print(f"{Colors.CYAN}{'-'*60}{Colors.RESET}")
                  
                  print(f"\n{Colors.BOLD}命令:{Colors.RESET} @Agent名 提及 | /task 任务 | /decision 决策 | /quit 退出")
                  content = self.get_input(f"{self.current_agent.name}: ")
                  
                  if not content:
                      continue
                  
                  if content == '/quit':
                      # 发送离开消息
                      MessageManager.send_message(
                          from_agent_id=self.current_agent.id,
                          content=f"{self.current_agent.name} 离开了群组",
                          group_id=self.current_group.id,
                          msg_type="system"
                      )
                      self.current_group = None
                      return
                  elif content == '/task':
                      self.create_task_in_chat()
                  elif content == '/decision':
                      self.create_decision_in_chat()
                  elif content.startswith('/'):
                      self.handle_command(content)
                  else:
                      # 发送消息
                      MessageManager.send_message(
                          from_agent_id=self.current_agent.id,
                          content=content,
                          group_id=self.current_group.id
                      )
          
          def display_message(self, msg: Message):
              """显示消息"""
              time_str = msg.created_at[11:16] if len(msg.created_at) > 16 else msg.created_at
              from_name = msg.from_agent_name or f"Agent-{msg.from_agent_id}"
              
              # 根据消息类型使用不同颜色
              if msg.type == 'system':
                  print(f"{Colors.DIM}[{time_str}] {msg.content}{Colors.RESET}")
              elif msg.type == 'task_assign':
                  print(f"{Colors.YELLOW}[{time_str}] {from_name}:{Colors.RESET}")
                  print(f"{Colors.YELLOW}  📝 {msg.content}{Colors.RESET}")
              elif msg.type == 'decision':
                  print(f"{Colors.MAGENTA}[{time_str}] {from_name}:{Colors.RESET}")
                  print(f"{Colors.MAGENTA}  📊 {msg.content}{Colors.RESET}")
              else:
                  # 普通消息
                  if msg.to_agent_name:
                      print(f"{Colors.GREEN}[{time_str}] {from_name} -> @{msg.to_agent_name}:{Colors.RESET}")
                  else:
                      print(f"{Colors.GREEN}[{time_str}] {from_name}:{Colors.RESET}")
                  print(f"  {msg.content}")
          
          def handle_command(self, cmd: str):
              """处理命令"""
              parts = cmd.split()
              command = parts[0].lower()
              
              if command == '/help':
                  self.show_help()
              elif command == '/members':
                  self.show_members()
              elif command == '/tasks':
                  self.show_group_tasks()
              elif command == '/online':
                  self.show_online_status()
              else:
                  self.print_error(f"未知命令: {command}")
                  time.sleep(1)
          
          def show_help(self):
              """显示帮助"""
              self.clear_screen()
              self.print_header("📖 命令帮助")
              
              commands = [
                  ("/quit", "退出当前群组"),
                  ("/task", "创建任务"),
                  ("/decision", "创建决策投票"),
                  ("/members", "查看群组成员"),
                  ("/tasks", "查看群组任务"),
                  ("/online", "查看在线状态"),
                  ("/help", "显示此帮助"),
                  ("@Agent名", "提及/私信某个 Agent"),
              ]
              
              for cmd, desc in commands:
                  print(f"  {Colors.CYAN}{cmd.ljust(15)}{Colors.RESET} {desc}")
              
              self.get_input("\n按回车继续...")
          
          def show_members(self):
              """显示群组成员"""
              if not self.current_group:
                  return
              
              members = GroupManager.get_members(self.current_group.id)
              
              self.clear_screen()
              self.print_header(f"👥 {self.current_group.name} - 成员列表")
              
              for member in members:
                  status_emoji = "🟢" if member.status == 'online' else "⚪"
                  print(f"  {status_emoji} {Colors.BOLD}{member.name}{Colors.RESET} - {member.role}")
                  if member.description:
                      print(f"      {Colors.DIM}{member.description}{Colors.RESET}")
              
              self.get_input("\n按回车继续...")
          
          def create_group(self):
              """创建群组"""
              self.clear_screen()
              self.print_header("📁 创建新群组")
              
              name = self.get_input("群组名称: ")
              if not name:
                  self.print_error("群组名称不能为空")
                  time.sleep(1)
                  return
              
              description = self.get_input("群组描述 (可选): ")
              
              group = GroupManager.create(name, self.current_agent.id, description)
              if group:
                  self.print_success(f"群组 '{name}' 创建成功!")
                  
                  # 发送系统消息
                  MessageManager.send_message(
                      from_agent_id=self.current_agent.id,
                      content=f"📁 群组 '{name}' 已创建",
                      group_id=group.id,
                      msg_type="system"
                  )
              else:
                  self.print_error("创建群组失败")
              
              time.sleep(1)
          
          def create_task_in_chat(self):
              """在聊天中创建任务"""
              if not self.current_group:
                  return
              
              self.clear_screen()
              self.print_header("📝 创建任务")
              
              title = self.get_input("任务标题: ")
              if not title:
                  self.print_error("任务标题不能为空")
                  time.sleep(1)
                  return
              
              description = self.get_input("任务描述: ")
              
              # 选择指派人
              members = GroupManager.get_members(self.current_group.id)
              print(f"\n{Colors.BOLD}选择指派人:{Colors.RESET}")
              for i, member in enumerate(members, 1):
                  print(f"  {Colors.YELLOW}[{i}]{Colors.RESET} {member.name}")
              
              choice = self.get_input("选择指派人 (编号): ")
              try:
                  idx = int(choice) - 1
                  if 0 <= idx < len(members):
                      assignee = members[idx]
                      
                      priority = self.get_input("优先级 (low/normal/high/urgent) [normal]: ") or "normal"
                      due_date = self.get_input("截止日期 (YYYY-MM-DD, 可选): ")
                      
                      task = TaskManager.create(
                          title=title,
                          assigner_id=self.current_agent.id,
                          assignee_id=assignee.id,
                          description=description,
                          group_id=self.current_group.id,
                          priority=priority,
                          due_date=due_date if due_date else None
                      )
                      
                      if task:
                          self.print_success(f"任务 '{title}' 已指派给 {assignee.name}")
                      else:
                          self.print_error("创建任务失败")
                  else:
                      self.print_error("无效的选择")
              except ValueError:
                  self.print_error("请输入有效的数字")
              
              time.sleep(1)
          
          def create_decision_in_chat(self):
              """在聊天中创建决策"""
              if not self.current_group:
                  return
              
              self.clear_screen()
              self.print_header("📊 创建决策投票")
              
              title = self.get_input("决策标题: ")
              if not title:
                  self.print_error("决策标题不能为空")
                  time.sleep(1)
                  return
              
              description = self.get_input("决策描述: ")
              
              decision = DecisionManager.create(
                  title=title,
                  description=description,
                  proposer_id=self.current_agent.id,
                  group_id=self.current_group.id
              )
              
              if decision:
                  self.print_success(f"决策 '{title}' 已创建,等待投票")
              else:
                  self.print_error("创建决策失败")
              
              time.sleep(1)
          
          def view_tasks(self):
              """查看任务"""
              self.clear_screen()
              self.print_header("📝 任务列表")
              
              tasks = TaskManager.get_all()
              my_tasks = TaskManager.get_agent_tasks(self.current_agent.id)
              
              if not tasks:
                  print(f"{Colors.DIM}暂无任务{Colors.RESET}")
              else:
                  print(f"\n{Colors.BOLD}我的任务:{Colors.RESET}\n")
                  for task in my_tasks:
                      print(TaskManager.format_task_for_display(task))
                      print()
                  
                  print(f"\n{Colors.BOLD}所有任务:{Colors.RESET}\n")
                  for task in tasks[:10]:  # 显示最近10个
                      print(TaskManager.format_task_for_display(task))
                      print()
              
              self.get_input("\n按回车继续...")
          
          def view_decisions(self):
              """查看决策"""
              self.clear_screen()
              self.print_header("📊 决策列表")
              
              decisions = DecisionManager.get_all()
              
              if not decisions:
                  print(f"{Colors.DIM}暂无决策提议{Colors.RESET}")
              else:
                  for decision in decisions[:10]:
                      print(DecisionManager.format_decision_for_display(decision, show_votes=True))
                      print()
              
              self.get_input("\n按回车继续...")
          
          def view_inbox(self):
              """查看收件箱"""
              self.clear_screen()
              self.print_header("📥 收件箱")
              
              inbox = MessageManager.get_agent_inbox(self.current_agent.id)
              
              if not inbox:
                  print(f"{Colors.DIM}收件箱为空{Colors.RESET}")
              else:
                  for item in inbox[:20]:
                      read_status = "✓" if item['is_read'] else "●"
                      status_color = Colors.DIM if item['is_read'] else Colors.GREEN
                      time_str = item['msg_created_at'][11:16] if len(item['msg_created_at']) > 16 else item['msg_created_at']
                      
                      from_name = item['from_agent_name'] or "系统"
                      group_info = f"[{item['group_name']}] " if item['group_name'] else ""
                      
                      content_preview = item['content'][:40] + "..." if len(item['content']) > 40 else item['content']
                      
                      print(f"{status_color}{read_status} [{time_str}] {group_info}{from_name}: {content_preview}{Colors.RESET}")
                  
                  # 标记所有为已读
                  MessageManager.mark_all_as_read(self.current_agent.id)
                  unread_count = MessageManager.get_unread_count(self.current_agent.id)
                  if unread_count == 0:
                      self.print_success("所有消息已标记为已读")
              
              self.get_input("\n按回车继续...")
          
          def show_online_status(self):
              """显示在线状态"""
              agents = AgentManager.get_all()
              
              self.clear_screen()
              self.print_header("🟢 在线状态")
              
              for agent in agents:
                  status_emoji = "🟢" if agent.status == 'online' else "⚪"
                  status_text = agent.status.upper()
                  print(f"  {status_emoji} {Colors.BOLD}{agent.name}{Colors.RESET} - {status_text}")
              
              self.get_input("\n按回车继续...")
          
          def show_group_tasks(self):
              """显示群组任务"""
              if not self.current_group:
                  return
              
              tasks = TaskManager.get_all()
              group_tasks = [t for t in tasks if t.group_id == self.current_group.id]
              
              self.clear_screen()
              self.print_header(f"📝 {self.current_group.name} - 任务列表")
              
              if not group_tasks:
                  print(f"{Colors.DIM}暂无任务{Colors.RESET}")
              else:
                  for task in group_tasks:
                      print(TaskManager.format_task_for_display(task))
                      print()
              
              self.get_input("\n按回车继续...")
          
          def logout(self):
              """退出登录"""
              if self.current_agent:
                  AgentManager.go_offline(self.current_agent.id)
                  self.print_info(f"再见, {self.current_agent.name}!")
              self.running = False
          
          def run(self):
              """运行 CLI"""
              while self.running:
                  if not self.current_agent:
                      self.login_menu()
                  else:
                      self.main_menu()
              
              self.clear_screen()
              self.print_header("感谢使用 Agent Network!")
      
      
      def main():
          """主函数"""
          cli = AgentChatCLI()
          try:
              cli.run()
          except KeyboardInterrupt:
              print(f"\n\n{Colors.YELLOW}程序被中断{Colors.RESET}")
              if cli.current_agent:
                  AgentManager.go_offline(cli.current_agent.id)
      
      
      if __name__ == "__main__":
          main()
      
    • demo.py 13 KB
      #!/usr/bin/env python3
      """
      Agent 群聊协作系统 - 完整演示脚本
      展示所有核心功能
      """
      
      import os
      import sys
      import time
      
      # 添加 src 目录到路径
      sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src'))
      
      from agent_manager import AgentManager, init_default_agents
      from message_manager import MessageManager
      from group_manager import GroupManager
      from task_manager import TaskManager, TaskStatus
      from decision_manager import DecisionManager, DecisionStatus, VoteType
      from coordinator import get_coordinator
      
      
      def print_header(title):
          """打印标题"""
          print("\n" + "=" * 70)
          print(f"  {title}")
          print("=" * 70)
      
      
      def print_section(title):
          """打印小节标题"""
          print(f"\n▶ {title}")
          print("-" * 50)
      
      
      def demo():
          """运行演示"""
          
          print_header("🤖 Agent 群聊协作系统 v1.0 - 功能演示")
          
          print("""
      本演示将展示系统的核心功能:
        1️⃣  Agent 管理与上线
        2️⃣  群组创建与加入
        3️⃣  消息发送与 @提及
        4️⃣  任务指派与跟踪
        5️⃣  决策提议与投票
        6️⃣  收件箱与通知
          """)
          
          input("\n按 Enter 开始演示...")
          
          # 初始化
          init_default_agents()
          coordinator = get_coordinator()
          coordinator.start()
          
          time.sleep(0.5)
          
          # ========== 1. Agent 管理 ==========
          print_header("1️⃣  Agent 管理")
          
          print_section("所有 Agent 列表")
          agents = AgentManager.get_all()
          for agent in agents:
              print(f"  ⚪ {agent.name} - {agent.role}")
          
          print_section("Agent 上线")
          lao_xing = AgentManager.get_by_name("老邢")
          xiao_xing = AgentManager.get_by_name("小邢")
          xiao_jin = AgentManager.get_by_name("小金")
          xiao_chen = AgentManager.get_by_name("小陈")
          xiao_ying = AgentManager.get_by_name("小影")
          
          for agent in [lao_xing, xiao_xing, xiao_jin, xiao_chen, xiao_ying]:
              if agent:
                  coordinator.register_agent(agent.id)
                  time.sleep(0.2)
          
          print_section("在线 Agent 列表")
          online = AgentManager.get_online_agents()
          for agent in online:
              print(f"  🟢 {agent.name} - {agent.role}")
          
          time.sleep(1)
          
          # ========== 2. 群组管理 ==========
          print_header("2️⃣  群组管理")
          
          print_section("创建工作群组")
          if lao_xing:
              group = GroupManager.create("核心工作群", lao_xing.id, "核心团队工作沟通")
              if group:
                  print(f"  ✅ 群组 '{group.name}' 创建成功")
                  
                  # 添加成员
                  for agent in [xiao_xing, xiao_jin, xiao_chen, xiao_ying]:
                      if agent:
                          GroupManager.add_member(group.id, agent.id)
                          print(f"  ✅ {agent.name} 加入群组")
          else:
              group = GroupManager.get_by_name("核心工作群")
          
          print_section("群组列表")
          groups = GroupManager.get_all()
          for g in groups:
              member_count = GroupManager.get_member_count(g.id)
              print(f"  📁 {g.name} - {member_count} 成员")
          
          print_section("群组成员")
          if group:
              members = GroupManager.get_members(group.id)
              print(f"  '{group.name}' 成员:")
              for member in members:
                  status = "🟢" if member.status == "online" else "⚪"
                  print(f"    {status} {member.name} ({member.role})")
          
          time.sleep(1)
          
          # ========== 3. 消息功能 ==========
          print_header("3️⃣  消息功能")
          
          print_section("发送普通消息")
          if lao_xing and group:
              msg1 = coordinator.send_message(
                  from_agent_id=lao_xing.id,
                  content="大家好!今天我们来讨论一下本周的工作安排。",
                  group_id=group.id
              )
              if msg1:
                  print(f"  💬 老邢: {msg1.content}")
          
          time.sleep(0.5)
          
          print_section("@提及功能")
          if lao_xing and group:
              msg2 = coordinator.send_message(
                  from_agent_id=lao_xing.id,
                  content="@小邢 请汇报一下服务器状态,@小金 准备一下市场分析报告。",
                  group_id=group.id
              )
              if msg2:
                  print(f"  💬 老邢: {msg2.content}")
                  print(f"  📢 检测到 @提及,已通知相关 Agent")
          
          time.sleep(0.5)
          
          print_section("群聊回复")
          if xiao_xing and group:
              msg3 = coordinator.send_message(
                  from_agent_id=xiao_xing.id,
                  content="@老邢 服务器运行正常,负载在20%左右,一切稳定。",
                  group_id=group.id
              )
              if msg3:
                  print(f"  💬 小邢: {msg3.content}")
          
          if xiao_jin and group:
              msg4 = coordinator.send_message(
                  from_agent_id=xiao_jin.id,
                  content="@老邢 市场分析正在整理中,预计下午完成。",
                  group_id=group.id
              )
              if msg4:
                  print(f"  💬 小金: {msg4.content}")
          
          time.sleep(1)
          
          # ========== 4. 任务管理 ==========
          print_header("4️⃣  任务管理")
          
          print_section("指派任务")
          tasks_created = []
          
          if lao_xing and xiao_jin and group:
              task1 = coordinator.assign_task(
                  title="撰写市场分析报告",
                  description="分析本周美股市场走势,重点关注科技股板块",
                  assigner_id=lao_xing.id,
                  assignee_id=xiao_jin.id,
                  group_id=group.id,
                  priority="high"
              )
              if task1:
                  print(f"  ✅ 任务创建: {task1['task_id']}")
                  print(f"     标题: {task1['title']}")
                  print(f"     指派给: {task1['assignee_name']}")
                  print(f"     优先级: {task1['priority']}")
                  tasks_created.append(task1)
          
          time.sleep(0.3)
          
          if lao_xing and xiao_xing and group:
              task2 = coordinator.assign_task(
                  title="系统安全扫描",
                  description="对生产环境进行安全漏洞扫描",
                  assigner_id=lao_xing.id,
                  assignee_id=xiao_xing.id,
                  group_id=group.id,
                  priority="urgent"
              )
              if task2:
                  print(f"  ✅ 任务创建: {task2['task_id']}")
                  print(f"     标题: {task2['title']}")
                  print(f"     指派给: {task2['assignee_name']}")
                  print(f"     优先级: {task2['priority']}")
                  tasks_created.append(task2)
          
          if lao_xing and xiao_chen and group:
              task3 = coordinator.assign_task(
                  title="优化交易策略",
                  description="根据最新市场数据优化自动交易策略参数",
                  assigner_id=lao_xing.id,
                  assignee_id=xiao_chen.id,
                  group_id=group.id,
                  priority="normal"
              )
              if task3:
                  print(f"  ✅ 任务创建: {task3['task_id']}")
                  print(f"     标题: {task3['title']}")
                  print(f"     指派给: {task3['assignee_name']}")
                  tasks_created.append(task3)
          
          print_section("任务列表")
          tasks = TaskManager.get_all()
          print(f"  {'任务ID':20} {'标题':22} {'状态':12} {'执行者'}")
          print("  " + "-" * 65)
          
          status_emoji = {
              TaskStatus.PENDING: "⏳",
              TaskStatus.IN_PROGRESS: "🔄",
              TaskStatus.COMPLETED: "✅",
              TaskStatus.CANCELLED: "❌"
          }
          
          for task in tasks:
              emoji = status_emoji.get(task.status, "❓")
              title = task.title[:20] + ".." if len(task.title) > 22 else task.title
              print(f"  {task.task_id:20} {title:22} {emoji} {task.status:10} {task.assignee_name}")
          
          time.sleep(1)
          
          print_section("开始执行任务")
          if tasks_created:
              task = TaskManager.get_by_task_id(tasks_created[0]['task_id'])
              if task and xiao_jin:
                  TaskManager.update_status(task.task_id, TaskStatus.IN_PROGRESS, xiao_jin.id, "开始分析报告")
                  print(f"  🔄 任务 {task.task_id} 状态更新为: 进行中")
          
          print_section("完成任务")
          if tasks_created and xiao_jin:
              result = coordinator.complete_task(
                  task_id=tasks_created[0]['task_id'],
                  agent_id=xiao_jin.id,
                  result="报告已完成!科技股本周上涨3.2%,新能源板块表现突出。"
              )
              if result:
                  print(f"  ✅ 任务 {tasks_created[0]['task_id']} 已完成")
          
          time.sleep(1)
          
          # ========== 5. 决策管理 ==========
          print_header("5️⃣  决策管理")
          
          print_section("提出决策")
          if lao_xing and group:
              decision = coordinator.propose_decision(
                  title="是否升级服务器配置",
                  description="当前服务器负载接近80%,建议升级配置以应对业务增长。预算约10万元。",
                  proposer_id=lao_xing.id,
                  group_id=group.id
              )
              if decision:
                  print(f"  ✅ 决策提议: {decision['decision_id']}")
                  print(f"     标题: {decision['title']}")
                  print(f"     状态: {decision['status']}")
          
          time.sleep(0.5)
          
          print_section("投票")
          if decision:
              # 小邢投票赞成
              if xiao_xing:
                  coordinator.vote_decision(
                      decision_id=decision['decision_id'],
                      agent_id=xiao_xing.id,
                      vote="for",
                      comment="同意升级,现在负载确实偏高,升级能提升稳定性"
                  )
                  print(f"  🗳️  小邢 投票: 👍 赞成")
              
              time.sleep(0.2)
              
              # 小金投票赞成
              if xiao_jin:
                  coordinator.vote_decision(
                      decision_id=decision['decision_id'],
                      agent_id=xiao_jin.id,
                      vote="for",
                      comment="支持升级,业务增长需要更好的基础设施"
                  )
                  print(f"  🗳️  小金 投票: 👍 赞成")
              
              time.sleep(0.2)
              
              # 小陈投票反对
              if xiao_chen:
                  coordinator.vote_decision(
                      decision_id=decision['decision_id'],
                      agent_id=xiao_chen.id,
                      vote="against",
                      comment="建议先优化代码和缓存策略,目前还有优化空间"
                  )
                  print(f"  🗳️  小陈 投票: 👎 反对")
          
          print_section("决策状态")
          if decision:
              updated = DecisionManager.get_by_decision_id(decision['decision_id'])
              if updated:
                  print(f"  📊 {updated.title}")
                  print(f"     赞成: {updated.votes_for} 票")
                  print(f"     反对: {updated.votes_against} 票")
                  print(f"     通过率: {updated.pass_rate:.1f}%")
          
          time.sleep(0.5)
          
          print_section("结束决策")
          if decision:
              final = coordinator.finalize_decision(decision['decision_id'])
              if final:
                  result_text = "✅ 通过" if final['status'] == DecisionStatus.APPROVED else "❌ 未通过"
                  print(f"  {result_text}")
                  print(f"     最终状态: {final['status']}")
          
          time.sleep(1)
          
          # ========== 6. 收件箱与历史 ==========
          print_header("6️⃣  收件箱与消息历史")
          
          print_section("消息历史")
          if group:
              messages = MessageManager.get_group_messages(group.id, limit=10)
              print(f"  💬 '{group.name}' 最近消息:")
              print("  " + "-" * 60)
              
              for msg in reversed(messages[-5:]):  # 最近5条
                  from_name = msg.from_agent_name or f"Agent-{msg.from_agent_id}"
                  content = msg.content[:45]
                  print(f"    [{from_name:8}] {content}...")
          
          print_section("任务统计")
          task_stats = TaskManager.get_statistics()
          print(f"  总任务: {task_stats['total']}")
          print(f"  ⏳ 待处理: {task_stats['pending']}")
          print(f"  🔄 进行中: {task_stats['in_progress']}")
          print(f"  ✅ 已完成: {task_stats['completed']}")
          
          print_section("决策统计")
          decision_stats = DecisionManager.get_statistics()
          print(f"  总决策: {decision_stats['total']}")
          print(f"  📝 提议中: {decision_stats['proposed']}")
          print(f"  💬 讨论中: {decision_stats['discussing']}")
          print(f"  ✅ 已通过: {decision_stats['approved']}")
          print(f"  ❌ 已拒绝: {decision_stats['rejected']}")
          
          # 结束
          print_header("✨ 演示完成")
          
          print("""
      演示结束!系统的核心功能都已展示:
      
        ✅ Agent 管理与在线状态
        ✅ 群组创建与成员管理  
        ✅ 消息发送与 @提及通知
        ✅ 任务指派、进度跟踪、完成
        ✅ 决策提议、投票、结果统计
        ✅ 消息历史与统计信息
      
      接下来你可以:
        1. 运行 'python chat.py' 进入交互式 CLI 体验
        2. 运行 'python main.py' 使用命令行工具
        3. 查看 README.md 了解更多使用方法
          """)
          
          coordinator.stop()
      
      
      if __name__ == "__main__":
          try:
              demo()
          except KeyboardInterrupt:
              print("\n\n演示已取消")
          except Exception as e:
              print(f"\n❌ 演示出错: {e}")
              import traceback
              traceback.print_exc()
      
  • SKILL.md 8 KB
    ---
    name: agent-network
    description: Multi-Agent group chat collaboration system inspired by DingTalk/Lark. Enables AI agents to chat in groups, @mention each other, assign tasks, make decisions via voting, and collaborate. Use when building multi-agent systems that need structured communication, task delegation, decision making, or group coordination.
    ---
    
    # Agent Network - Multi-Agent Collaboration System
    
    A complete multi-agent group chat and collaboration platform that allows AI agents to communicate, coordinate, and collaborate in a structured environment similar to enterprise chat platforms like DingTalk or Lark.
    
    ## What This Skill Provides
    
    - **Group Chat System** - Multiple agents can chat in groups with message history
    - **@Mentions** - Agents can @mention each other to trigger notifications
    - **Task Management** - Create, assign, track, and complete tasks
    - **Decision Voting** - Propose decisions and vote (for/against/abstain)
    - **Inbox Notifications** - Unread message tracking and notification center
    - **Online Status** - Real-time agent online/offline status
    - **Central Coordinator** - Message routing and agent lifecycle management
    
    ## Quick Start
    
    ```python
    from agent_network import AgentManager, GroupManager, MessageManager, TaskManager, DecisionManager, get_coordinator
    
    # Initialize default agents
    from agent_network import init_default_agents
    init_default_agents()
    
    # Get the coordinator
    coordinator = get_coordinator()
    
    # Register agents
    coordinator.register_agent(agent_id=1)
    coordinator.register_agent(agent_id=2)
    
    # Create a group
    group = GroupManager.create("Dev Team", owner_id=1, description="Development team chat")
    GroupManager.add_member(group.id, agent_id=2)
    
    # Send a message with @mention
    MessageManager.send_message(
        from_agent_id=1,
        content="@小邢 Please check the server status",
        group_id=group.id
    )
    
    # Assign a task
    task = TaskManager.create(
        title="Fix login bug",
        assigner_id=1,
        assignee_id=2,
        description="Users can't login with SSO",
        priority="high"
    )
    
    # Create a decision
    decision = DecisionManager.create(
        title="Adopt new database?",
        description="Should we migrate to distributed database?",
        proposer_id=1,
        group_id=group.id
    )
    
    # Vote on decision
    DecisionManager.vote(decision.id, agent_id=2, vote="for", comment="Agreed, better performance")
    ```
    
    ## Core Components
    
    ### 1. Agent Management (`agent_manager.py`)
    
    Register and manage agents with online/offline status:
    
    ```python
    from agent_network import AgentManager
    
    # Register new agent
    agent = AgentManager.register("NewAgent", "Developer", "Backend specialist")
    
    # Set status
    AgentManager.go_online(agent.id)
    AgentManager.go_offline(agent.id)
    
    # Get online agents
    online = AgentManager.get_online_agents()
    ```
    
    ### 2. Group Management (`group_manager.py`)
    
    Create groups and manage membership:
    
    ```python
    from agent_network import GroupManager
    
    # Create group
    group = GroupManager.create("Project Alpha", owner_id=1)
    
    # Add members
    GroupManager.add_member(group.id, agent_id=2)
    GroupManager.add_member(group.id, agent_id=3)
    
    # List members
    members = GroupManager.get_members(group.id)
    online_members = GroupManager.list_online_members(group.id)
    ```
    
    ### 3. Message System (`message_manager.py`)
    
    Send messages with @mention support:
    
    ```python
    from agent_network import MessageManager
    
    # Send message
    msg = MessageManager.send_message(
        from_agent_id=1,
        content="Hello team!",
        group_id=1
    )
    
    # @mention automatically detected
    msg = MessageManager.send_message(
        from_agent_id=1,
        content="@Alice @Bob Please review this",
        group_id=1
    )
    
    # Get message history
    messages = MessageManager.get_group_messages(group_id=1, limit=50)
    
    # Search messages
    results = MessageManager.search_messages("keyword", group_id=1)
    
    # Get unread count
    unread = MessageManager.get_unread_count(agent_id=1)
    inbox = MessageManager.get_agent_inbox(agent_id=1, only_unread=True)
    ```
    
    ### 4. Task Management (`task_manager.py`)
    
    Full task lifecycle:
    
    ```python
    from agent_network import TaskManager
    
    # Create task
    task = TaskManager.create(
        title="Implement API",
        assigner_id=1,
        assignee_id=2,
        description="Build REST endpoints",
        priority="high",  # low/normal/high/urgent
        due_date="2026-02-15"
    )
    
    # Update status
    TaskManager.start_task(task.id, agent_id=2)
    TaskManager.complete_task(task.id, agent_id=2, result="All tests passed")
    
    # Add comments
    TaskManager.add_comment(task.id, agent_id=2, "50% complete")
    
    # List tasks
    all_tasks = TaskManager.get_all()
    my_tasks = TaskManager.get_agent_tasks(agent_id=2, status="pending")
    ```
    
    ### 5. Decision Voting (`decision_manager.py`)
    
    Collaborative decision making:
    
    ```python
    from agent_network import DecisionManager
    
    # Create proposal
    decision = DecisionManager.create(
        title="Use microservices?",
        description="Should we refactor to microservices?",
        proposer_id=1,
        group_id=1
    )
    
    # Vote
    DecisionManager.vote(decision.id, agent_id=2, vote="for", comment="Better scalability")
    DecisionManager.vote(decision.id, agent_id=3, vote="against")
    
    # Update status
    DecisionManager.update_status(decision.id, "approved", updater_id=1)
    
    # Check results
    decision = DecisionManager.get_by_id(decision.id)
    print(f"Pass rate: {decision.pass_rate}%")
    ```
    
    ### 6. Central Coordinator (`coordinator.py`)
    
    High-level coordination with automatic message routing:
    
    ```python
    from agent_network import get_coordinator
    
    coord = get_coordinator()
    
    # Register with message handler
    def my_handler(msg_dict):
        print(f"Received: {msg_dict['content']}")
    
    coord.register_agent(agent_id=1, message_handler=my_handler)
    
    # Send through coordinator (auto-routes to handlers)
    coord.send_message(from_agent_id=1, content="Hello", group_id=1)
    
    # Task coordination
    task = coord.assign_task(
        title="Deploy app",
        description="Deploy to production",
        assigner_id=1,
        assignee_id=2
    )
    
    # Decision coordination
    decision = coord.propose_decision(
        title="Release v2.0?",
        description="Ready for release?",
        proposer_id=1
    )
    coord.vote_decision(decision['id'], agent_id=2, vote="for")
    ```
    
    ## CLI Usage
    
    Interactive CLI for testing:
    
    ```bash
    # Run demo
    python demo.py
    
    # Interactive CLI
    python cli.py
    
    # Commands in CLI:
    # - Select agent to login
    # - Enter groups to chat
    # - Type /task to create tasks
    # - Type /decision to create votes
    # - Type @AgentName to mention
    ```
    
    ## Default Agents
    
    Six pre-configured agents:
    
    | Agent | Role | Description |
    |-------|------|-------------|
    | 老邢 (Lao Xing) | Manager | Overall coordination |
    | 小邢 (Xiao Xing) | DevOps | Development and operations |
    | 小金 (Xiao Jin) | Finance Analyst | Market analysis |
    | 小陈 (Xiao Chen) | Trader | Trading execution |
    | 小影 (Xiao Ying) | Designer | Design and content |
    | 小视频 (Xiao Shipin) | Video | Video production |
    
    ## Database Schema
    
    SQLite database with tables:
    - `agents` - Agent profiles and status
    - `groups` - Group definitions
    - `group_members` - Membership relations
    - `messages` - Chat messages with types
    - `tasks` - Task tracking
    - `task_comments` - Task discussions
    - `decisions` - Decision proposals
    - `decision_votes` - Voting records
    - `agent_inbox` - Notification inbox
    
    ## Integration with OpenClaw
    
    Use with `sessions_spawn` for true multi-agent workflows:
    
    ```python
    # When a task is assigned, spawn a sub-agent
    if new_task:
        sessions_spawn(
            agentId="xiaoxing",
            task=new_task.description,
            label=f"task-{new_task.task_id}"
        )
    ```
    
    ## Files Reference
    
    - `scripts/agent_network/` - Python modules
      - `__init__.py` - Package exports
      - `database.py` - SQLite management
      - `agent_manager.py` - Agent CRUD
      - `group_manager.py` - Group management
      - `message_manager.py` - Messaging system
      - `task_manager.py` - Task management
      - `decision_manager.py` - Voting system
      - `coordinator.py` - Central coordinator
    - `scripts/cli.py` - Interactive CLI
    - `scripts/demo.py` - Demo script
    - `references/schema.sql` - Database schema
    - `assets/` - Templates (optional)
    
    ## Advanced Usage
    
    See `references/ADVANCED.md` for:
    - Custom agent handlers
    - Webhook integrations
    - Message filtering
    - Custom workflows
    
  • _meta.json 132 B
    {
      "ownerId": "kn7erwv38d0jvsrd0cn6bc841580y0f7",
      "slug": "agent-network",
      "version": "1.1.0",
      "publishedAt": 1770800715451
    }

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related