Compare commits
3 Commits
a4c9433aac
...
668452c3ee
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
668452c3ee | ||
|
|
2d607486e5 | ||
|
|
5ab55919bc |
@ -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
|
||||||
@ -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)
|
||||||
|
|||||||
@ -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}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user