Compare commits

...

3 Commits

Author SHA1 Message Date
Your Name
668452c3ee ragflow 2026-02-24 00:03:19 +08:00
Your Name
2d607486e5 Merge branch 'bot_manager' of https://git.aitravelmaster.com/zhuchaowe/qwen_agent into bot_manager 2026-02-24 00:01:46 +08:00
朱潮
5ab55919bc 移除admin可看到所有bot的能力 2026-02-24 00:00:23 +08:00
3 changed files with 49 additions and 83 deletions

View File

@ -1,7 +1,7 @@
version: "3.8" version: "3.8"
services: services:
postgres: postgres-agent:
image: pgvector/pgvector:pg16 image: pgvector/pgvector:pg16
container_name: qwen-agent-postgres container_name: qwen-agent-postgres
environment: environment:
@ -29,20 +29,19 @@ services:
- "8001:8001" - "8001:8001"
environment: environment:
# 应用配置 # 应用配置
- BACKEND_HOST=http://api-dev.gbase.ai
- MAX_CONTEXT_TOKENS=262144 - MAX_CONTEXT_TOKENS=262144
- DEFAULT_THINKING_ENABLE=true - DEFAULT_THINKING_ENABLE=true
- PROFILE=low_memory - PROFILE=low_memory
- RAGFLOW_API_URL=http://172.26.31.232:1080 - RAGFLOW_API_URL=http://ragflow-cpu
- RAGFLOW_API_KEY=ragflow-0vldzYY_SfQLnjBIGOBDDgvdgWemdK4gmH1L7kgenQ0 - RAGFLOW_API_KEY=ragflow-0vldzYY_SfQLnjBIGOBDDgvdgWemdK4gmH1L7kgenQ0
# PostgreSQL 配置 # PostgreSQL 配置
- CHECKPOINT_DB_URL=postgresql://postgres:E5ACJo6zJub4QS@postgres:5432/agent_db - CHECKPOINT_DB_URL=postgresql://postgres:E5ACJo6zJub4QS@postgres-agent:5432/agent_db
volumes: volumes:
# 挂载项目数据目录 # 挂载项目数据目录
- ./projects:/app/projects - ./projects:/app/projects
- ./models:/app/models - ./models:/app/models
depends_on: depends_on:
postgres: postgres-agent:
condition: service_healthy condition: service_healthy
restart: unless-stopped restart: unless-stopped
healthcheck: healthcheck:
@ -51,5 +50,12 @@ services:
timeout: 10s timeout: 10s
retries: 3 retries: 3
start_period: 40s start_period: 40s
networks:
- default
- ragflow
volumes: volumes:
postgres_data: postgres_data:
networks:
ragflow:
name: docker_ragflow
external: true

View File

@ -1314,87 +1314,47 @@ async def get_bots(authorization: Optional[str] = Header(None)):
detail="Unauthorized" detail="Unauthorized"
) )
# 检查是否是管理员
pool = get_db_pool_manager().pool pool = get_db_pool_manager().pool
async with pool.connection() as conn: async with pool.connection() as conn:
async with conn.cursor() as cursor: async with conn.cursor() as cursor:
# 所有用户(包括 admin只能看到拥有的 Bot 和分享给自己的 Bot且未过期
await cursor.execute(""" await cursor.execute("""
SELECT is_admin FROM agent_user WHERE id = %s SELECT DISTINCT b.id, b.name, b.bot_id, b.created_at, b.updated_at, b.settings,
""", (user_id,)) u.id as owner_id, u.username as owner_username,
row = await cursor.fetchone() s.role, s.shared_at, s.expires_at,
is_admin = row and row[0] b.is_published, b.copied_from
FROM agent_bots b
LEFT JOIN agent_user u ON b.owner_id = u.id
LEFT JOIN bot_shares s ON b.id = s.bot_id AND s.user_id = %s
WHERE b.owner_id = %s
OR (s.user_id IS NOT NULL
AND s.user_id = %s
AND (s.expires_at IS NULL OR s.expires_at > NOW()))
ORDER BY b.created_at DESC
""", (user_id, user_id, user_id))
rows = await cursor.fetchall()
async with pool.connection() as conn: return [
async with conn.cursor() as cursor: BotResponse(
if is_admin: id=str(row[0]),
# 管理员可以看到所有 Bot name=row[1],
await cursor.execute(""" bot_id=str(row[0]),
SELECT b.id, b.name, b.bot_id, b.created_at, b.updated_at, b.settings, is_owner=(row[6] is not None and str(row[6]) == user_id),
u.id as owner_id, u.username as owner_username, is_shared=(row[6] is not None and str(row[6]) != user_id and row[8] is not None),
b.is_published, b.copied_from is_published=row[11] if row[11] else False,
FROM agent_bots b copied_from=str(row[12]) if row[12] else None,
LEFT JOIN agent_user u ON b.owner_id = u.id owner={"id": str(row[6]), "username": row[7]} if row[6] is not None else None,
ORDER BY b.created_at DESC role=row[8] if row[8] is not None else None,
""") shared_at=datetime_to_str(row[9]) if row[9] is not None else None,
rows = await cursor.fetchall() expires_at=row[10].isoformat() if row[10] is not None else None,
description=row[5].get('description') if row[5] else None,
return [ avatar_url=row[5].get('avatar_url') if row[5] else None,
BotResponse( created_at=datetime_to_str(row[3]),
id=str(row[0]), # 使用 UUID 主键 updated_at=datetime_to_str(row[4])
name=row[1], )
bot_id=str(row[0]), # bot_id 也指向主键 id for row in rows
is_owner=True, ]
is_shared=False,
is_published=row[8] if row[8] else False,
copied_from=str(row[9]) if row[9] else None,
owner={"id": str(row[6]), "username": row[7]} if row[6] else None,
role=None,
description=row[5].get('description') if row[5] else None,
avatar_url=row[5].get('avatar_url') if row[5] else None,
created_at=datetime_to_str(row[3]),
updated_at=datetime_to_str(row[4])
)
for row in rows
]
else:
# 用户只能看到拥有的 Bot 和分享给自己的 Bot且未过期
# 使用子查询确保正确过滤,避免 LEFT JOIN 导致的 NULL 值比较问题
await cursor.execute("""
SELECT DISTINCT b.id, b.name, b.bot_id, b.created_at, b.updated_at, b.settings,
u.id as owner_id, u.username as owner_username,
s.role, s.shared_at, s.expires_at,
b.is_published, b.copied_from
FROM agent_bots b
LEFT JOIN agent_user u ON b.owner_id = u.id
LEFT JOIN bot_shares s ON b.id = s.bot_id AND s.user_id = %s
WHERE b.owner_id = %s
OR (s.user_id IS NOT NULL
AND s.user_id = %s
AND (s.expires_at IS NULL OR s.expires_at > NOW()))
ORDER BY b.created_at DESC
""", (user_id, user_id, user_id))
rows = await cursor.fetchall()
return [
BotResponse(
id=str(row[0]), # 使用 UUID 主键
name=row[1],
bot_id=str(row[0]), # bot_id 也指向主键 id
is_owner=(row[6] is not None and str(row[6]) == user_id),
is_shared=(row[6] is not None and str(row[6]) != user_id and row[8] is not None),
is_published=row[11] if row[11] else False,
copied_from=str(row[12]) if row[12] else None,
owner={"id": str(row[6]), "username": row[7]} if row[6] is not None else None,
role=row[8] if row[8] is not None else None,
shared_at=datetime_to_str(row[9]) if row[9] is not None else None,
expires_at=row[10].isoformat() if row[10] is not None else None,
description=row[5].get('description') if row[5] else None,
avatar_url=row[5].get('avatar_url') if row[5] else None,
created_at=datetime_to_str(row[3]),
updated_at=datetime_to_str(row[4])
)
for row in rows
]
@router.post("/api/v1/bots", response_model=BotResponse) @router.post("/api/v1/bots", response_model=BotResponse)

View File

@ -12,9 +12,9 @@
"mcpServers": { "mcpServers": {
"rag_retrieve": { "rag_retrieve": {
"transport": "http", "transport": "http",
"url": "http://host.docker.internal:9382/mcp/", "url": "http://ragflow-cpu:9382/mcp/",
"headers": { "headers": {
"api_key": "ragflow-MRqxnDnYZ1yp5kklDMIlKH4f1qezvXIngSMGPhu1AG8", "api_key": "ragflow-0vldzYY_SfQLnjBIGOBDDgvdgWemdK4gmH1L7kgenQ0",
"X-Dataset-Ids": "{dataset_ids}" "X-Dataset-Ids": "{dataset_ids}"
} }
} }