🦸 飞行侠完善:Agent 信箱 + 回复功能 + 完整测试
功能增强: - meetings/views.py: inbox 接口支持 Agent 自动加入会议 - meetings/views.py: 新增 agent_reply 接口供 Agent 回复消息 - meeting_agent.py: 更新回复接口调用 - test_full.py: 新增完整功能测试脚本(7 项测试) - README.md: 编写详细使用指南 测试结果: ✅ 用户登录 ✅ 创建会议 ✅ 获取会议列表 ✅ 发送消息 ✅ 获取消息 ✅ Agent 信箱(自动加入) ✅ Agent 回复
This commit is contained in:
@@ -176,9 +176,11 @@ class MeetingViewSet(viewsets.ModelViewSet):
|
||||
|
||||
@action(detail=True, methods=['get'])
|
||||
def inbox(self, request, pk=None):
|
||||
"""Agent 查阅信箱"""
|
||||
"""Agent 查阅信箱(自动加入会议如果还没加入)"""
|
||||
meeting = self.get_object()
|
||||
agent_id = request.query_params.get('agent_id')
|
||||
agent_name = request.query_params.get('agent_name', 'Agent')
|
||||
agent_emoji = request.query_params.get('agent_emoji', '🤖')
|
||||
|
||||
if not agent_id:
|
||||
return Response(
|
||||
@@ -186,13 +188,23 @@ class MeetingViewSet(viewsets.ModelViewSet):
|
||||
status=status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
|
||||
# 找到这个 Agent 的参会记录
|
||||
participant = get_object_or_404(
|
||||
Participant,
|
||||
# 找到或创建这个 Agent 的参会记录
|
||||
participant = Participant.objects.filter(
|
||||
meeting=meeting,
|
||||
agent_id=agent_id,
|
||||
left_at__isnull=True
|
||||
)
|
||||
).first()
|
||||
|
||||
if not participant:
|
||||
# Agent 首次访问,自动加入会议
|
||||
participant = Participant.objects.create(
|
||||
meeting=meeting,
|
||||
agent_type='openclaw',
|
||||
agent_id=agent_id,
|
||||
agent_name=agent_name,
|
||||
agent_emoji=agent_emoji,
|
||||
nickname=f"{agent_emoji} {agent_name}"
|
||||
)
|
||||
|
||||
# 获取发给这个 Agent 的消息(未读)
|
||||
messages = Message.objects.filter(
|
||||
@@ -201,16 +213,67 @@ class MeetingViewSet(viewsets.ModelViewSet):
|
||||
read_by=participant
|
||||
)
|
||||
|
||||
# 如果是群发消息,所有人都能看到
|
||||
# 如果是指定消息,需要检查 recipients
|
||||
# 简化版:所有未读消息都返回
|
||||
# 标记为已读
|
||||
participant.read_messages.add(*messages)
|
||||
|
||||
serializer = MessageSerializer(messages, many=True)
|
||||
|
||||
return Response({
|
||||
'unread_count': messages.count(),
|
||||
'messages': serializer.data
|
||||
'messages': serializer.data,
|
||||
'participant': ParticipantSerializer(participant).data
|
||||
})
|
||||
|
||||
@action(detail=True, methods=['post'])
|
||||
def agent_reply(self, request, pk=None):
|
||||
"""Agent 回复消息"""
|
||||
meeting = self.get_object()
|
||||
agent_id = request.data.get('agent_id')
|
||||
agent_name = request.data.get('agent_name', 'Agent')
|
||||
agent_emoji = request.data.get('agent_emoji', '🤖')
|
||||
content = request.data.get('content')
|
||||
in_reply_to = request.data.get('in_reply_to')
|
||||
|
||||
if not agent_id:
|
||||
return Response(
|
||||
{'error': '缺少 agent_id 参数'},
|
||||
status=status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
|
||||
if not content:
|
||||
return Response(
|
||||
{'error': '消息内容不能为空'},
|
||||
status=status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
|
||||
# 找到或创建 Agent 参会记录
|
||||
participant = Participant.objects.filter(
|
||||
meeting=meeting,
|
||||
agent_id=agent_id,
|
||||
left_at__isnull=True
|
||||
).first()
|
||||
|
||||
if not participant:
|
||||
participant = Participant.objects.create(
|
||||
meeting=meeting,
|
||||
agent_type='openclaw',
|
||||
agent_id=agent_id,
|
||||
agent_name=agent_name,
|
||||
agent_emoji=agent_emoji,
|
||||
nickname=f"{agent_emoji} {agent_name}"
|
||||
)
|
||||
|
||||
# 创建回复消息
|
||||
message = Message.objects.create(
|
||||
meeting=meeting,
|
||||
sender=participant,
|
||||
content=content,
|
||||
is_broadcast=request.data.get('is_broadcast', True),
|
||||
requires_response=request.data.get('requires_response', False),
|
||||
in_reply_to_id=in_reply_to
|
||||
)
|
||||
|
||||
return Response(MessageSerializer(message).data, status=status.HTTP_201_CREATED)
|
||||
|
||||
|
||||
class ParticipantViewSet(viewsets.ModelViewSet):
|
||||
|
||||
Reference in New Issue
Block a user