66 lines
2.3 KiB
Python
66 lines
2.3 KiB
Python
|
|
from django.db import models
|
|||
|
|
import uuid
|
|||
|
|
|
|||
|
|
|
|||
|
|
class Instance(models.Model):
|
|||
|
|
"""
|
|||
|
|
OpenClaw 实例注册
|
|||
|
|
|
|||
|
|
每台运行 OpenClaw 的机器注册一个实例,关联多个 Agent
|
|||
|
|
"""
|
|||
|
|
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
|||
|
|
instance_id = models.CharField(max_length=100, unique=True, verbose_name='实例 ID')
|
|||
|
|
instance_name = models.CharField(max_length=200, verbose_name='实例名称')
|
|||
|
|
|
|||
|
|
# Agent 列表(JSON 存储)
|
|||
|
|
agent_ids = models.JSONField(default=list, verbose_name='Agent ID 列表')
|
|||
|
|
|
|||
|
|
# Webhook 配置
|
|||
|
|
webhook_url = models.URLField(verbose_name='Webhook URL', help_text='消息推送地址')
|
|||
|
|
webhook_enabled = models.BooleanField(default=True, verbose_name='启用 Webhook')
|
|||
|
|
|
|||
|
|
# 状态
|
|||
|
|
is_active = models.BooleanField(default=True, verbose_name='是否活跃')
|
|||
|
|
last_heartbeat = models.DateTimeField(null=True, blank=True, verbose_name='最后心跳')
|
|||
|
|
|
|||
|
|
# 元数据
|
|||
|
|
created_at = models.DateTimeField(auto_now_add=True)
|
|||
|
|
updated_at = models.DateTimeField(auto_now=True)
|
|||
|
|
|
|||
|
|
class Meta:
|
|||
|
|
db_table = 'instances'
|
|||
|
|
verbose_name = 'OpenClaw 实例'
|
|||
|
|
verbose_name_plural = 'OpenClaw 实例'
|
|||
|
|
ordering = ['-created_at']
|
|||
|
|
|
|||
|
|
def __str__(self):
|
|||
|
|
return f"{self.instance_name} ({self.instance_id})"
|
|||
|
|
|
|||
|
|
def has_agent(self, agent_id: str) -> bool:
|
|||
|
|
"""检查是否包含某个 Agent"""
|
|||
|
|
return agent_id in self.agent_ids
|
|||
|
|
|
|||
|
|
|
|||
|
|
class MeetingInstanceMap(models.Model):
|
|||
|
|
"""
|
|||
|
|
会议 - 实例映射
|
|||
|
|
|
|||
|
|
记录哪些实例参与了哪些会议
|
|||
|
|
"""
|
|||
|
|
meeting_id = models.UUIDField(verbose_name='会议 ID')
|
|||
|
|
instance = models.ForeignKey(Instance, on_delete=models.CASCADE, related_name='meetings')
|
|||
|
|
agent_ids = models.JSONField(default=list, verbose_name='参与的 Agent ID 列表')
|
|||
|
|
|
|||
|
|
joined_at = models.DateTimeField(auto_now_add=True)
|
|||
|
|
left_at = models.DateTimeField(null=True, blank=True)
|
|||
|
|
|
|||
|
|
class Meta:
|
|||
|
|
db_table = 'meeting_instance_maps'
|
|||
|
|
unique_together = ['meeting_id', 'instance']
|
|||
|
|
indexes = [
|
|||
|
|
models.Index(fields=['meeting_id', 'left_at']),
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
def __str__(self):
|
|||
|
|
return f"Meeting {self.meeting_id} - {self.instance.instance_name}"
|