核心功能:
- 用户模型扩展:linked_agents 字段存储绑定龙虾
- 登录 API 支持 3 种模式:human_only / agent_only / both
- 龙虾管理 API:绑定/解绑/列表
- 扫描本机龙虾 API:从注册实例获取
API 端点:
- POST /api/v1/auth/login/ - 支持 login_mode 和 selected_agent_id
- GET /api/v1/user/linked-agents/ - 获取绑定龙虾
- POST /api/v1/user/linked-agents/ - 添加绑定龙虾
- DELETE /api/v1/user/linked-agents/{id}/ - 移除龙虾
- GET /api/v1/user/scan-local-agents/ - 扫描本机龙虾
登录模式:
1. human_only - 纯人类身份(1 个座位)
2. agent_only - 纯龙虾身份(1 个座位)
3. both - 双重身份(2 个座位)
测试:
- test_multi_identity.py: 完整测试通过
使用场景:
- 普通用户参会 → human_only
- 龙虾独立参会 → agent_only
- 用户带龙虾助理 → both
51 lines
1.7 KiB
Python
51 lines
1.7 KiB
Python
from django.contrib.auth.models import AbstractUser
|
||
from django.db import models
|
||
|
||
|
||
class User(AbstractUser):
|
||
"""扩展用户模型"""
|
||
email = models.EmailField(unique=True)
|
||
created_at = models.DateTimeField(auto_now_add=True)
|
||
|
||
# 绑定的龙虾列表(JSON 存储)
|
||
# 示例:[{"agent_id": "flying_hero", "agent_name": "飞行侠", "agent_emoji": "🦸", "instance_id": "phospher-openclaw"}]
|
||
linked_agents = models.JSONField(default=list, verbose_name='绑定的龙虾', blank=True)
|
||
|
||
class Meta:
|
||
db_table = 'users'
|
||
verbose_name = '用户'
|
||
verbose_name_plural = '用户'
|
||
# 避免与 auth.User 冲突
|
||
app_label = 'users'
|
||
|
||
def __str__(self):
|
||
return self.username
|
||
|
||
def add_linked_agent(self, agent_id: str, agent_name: str, agent_emoji: str = '🤖', instance_id: str = None):
|
||
"""添加绑定的龙虾"""
|
||
agent = {
|
||
'agent_id': agent_id,
|
||
'agent_name': agent_name,
|
||
'agent_emoji': agent_emoji,
|
||
'instance_id': instance_id
|
||
}
|
||
# 避免重复
|
||
for i, a in enumerate(self.linked_agents):
|
||
if a.get('agent_id') == agent_id:
|
||
self.linked_agents[i] = agent
|
||
return
|
||
self.linked_agents.append(agent)
|
||
self.save()
|
||
|
||
def remove_linked_agent(self, agent_id: str):
|
||
"""移除绑定的龙虾"""
|
||
self.linked_agents = [a for a in self.linked_agents if a.get('agent_id') != agent_id]
|
||
self.save()
|
||
|
||
def get_linked_agent(self, agent_id: str):
|
||
"""获取指定的龙虾信息"""
|
||
for agent in self.linked_agents:
|
||
if agent.get('agent_id') == agent_id:
|
||
return agent
|
||
return None
|