🎨 飞行侠完善 P1 功能:座位图 + @Agent + 会议纪要
新增功能: - 座位可视化 - 圆形头像展示参会者 - @Agent 功能 - 定向消息给特定 Agent - 会议纪要生成 - Web 界面一键生成 - 参会者列表 API 文件变更: - meetings/views.py: mention_agent() 新接口 - templates/meeting_room.html: - 座位图 UI(圆形头像) - 生成纪要按钮 - @Agent 按钮 - test_mention.py: @Agent 测试脚本 测试结果: ✅ 完整功能测试 (7 项) ✅ 会议纪要测试 (JSON + Markdown) ✅ @Agent 功能测试
This commit is contained in:
@@ -125,6 +125,70 @@ class MeetingViewSet(viewsets.ModelViewSet):
|
||||
serializer = ParticipantSerializer(participants, many=True)
|
||||
return Response(serializer.data)
|
||||
|
||||
@action(detail=True, methods=['post'])
|
||||
def mention_agent(self, request, pk=None):
|
||||
"""@Agent 功能 - 发送消息给特定 Agent"""
|
||||
meeting = self.get_object()
|
||||
target_agent_id = request.data.get('target_agent_id')
|
||||
content = request.data.get('content')
|
||||
sender_agent_id = request.data.get('sender_agent_id')
|
||||
sender_name = request.data.get('sender_name', 'User')
|
||||
sender_emoji = request.data.get('sender_emoji', '👤')
|
||||
|
||||
if not target_agent_id or not content:
|
||||
return Response(
|
||||
{'error': '缺少 target_agent_id 或 content'},
|
||||
status=status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
|
||||
# 找到目标 Agent
|
||||
target_participant = Participant.objects.filter(
|
||||
meeting=meeting,
|
||||
agent_id=target_agent_id,
|
||||
left_at__isnull=True
|
||||
).first()
|
||||
|
||||
if not target_participant:
|
||||
return Response(
|
||||
{'error': f'未找到 Agent: {target_agent_id}'},
|
||||
status=status.HTTP_404_NOT_FOUND
|
||||
)
|
||||
|
||||
# 获取或创建发送者
|
||||
sender_participant = Participant.objects.filter(
|
||||
meeting=meeting,
|
||||
agent_id=sender_agent_id,
|
||||
left_at__isnull=True
|
||||
).first()
|
||||
|
||||
if not sender_participant and sender_agent_id:
|
||||
sender_participant = Participant.objects.create(
|
||||
meeting=meeting,
|
||||
agent_type='openclaw',
|
||||
agent_id=sender_agent_id,
|
||||
agent_name=sender_name,
|
||||
agent_emoji=sender_emoji,
|
||||
nickname=f"{sender_emoji} {sender_name}"
|
||||
)
|
||||
|
||||
if not sender_participant:
|
||||
# 人类发送的,用主持人
|
||||
sender_participant = Participant.objects.filter(
|
||||
meeting=meeting,
|
||||
is_host=True
|
||||
).first()
|
||||
|
||||
# 创建消息,标记为需要回复
|
||||
message = Message.objects.create(
|
||||
meeting=meeting,
|
||||
sender=sender_participant,
|
||||
content=f"@{target_participant.nickname} {content}",
|
||||
is_broadcast=False, # 只发给目标 Agent
|
||||
requires_response=True
|
||||
)
|
||||
|
||||
return Response(MessageSerializer(message).data, status=status.HTTP_201_CREATED)
|
||||
|
||||
@action(detail=True, methods=['get'])
|
||||
def messages(self, request, pk=None):
|
||||
"""获取消息(人类轮询)"""
|
||||
|
||||
Reference in New Issue
Block a user