新功能: - instances 应用:OpenClaw 实例管理 - Instance 模型:实例注册,Agent 列表,Webhook URL - MeetingInstanceMap:会议 - 实例映射 - Webhook 推送:消息发送时自动通知相关实例 API 端点: - POST /api/v1/instances/register/ - 实例注册 - POST /api/v1/instances/join-meeting/ - 加入会议 - GET /api/v1/instances/ - 实例列表 - POST /api/v1/instances/webhook-test/ - Webhook 测试 集成: - send_message API 自动触发 Webhook 推送 - 支持广播和定向推送 测试: - test_webhook.py: 完整测试流程 使用场景: 1. 每台 OpenClaw 机器注册实例 2. Agent 加入会议时关联实例 3. 消息发送时推送到对应机器 4. 本机 OpenClaw 收到通知,触发 Agent 响应
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}"
|