update payment
This commit is contained in:
parent
d7dfd8810e
commit
98f23fa346
@ -60,23 +60,7 @@ CREATE TABLE IF NOT EXISTS agent_admin_tokens (
|
|||||||
CREATE INDEX IF NOT EXISTS idx_agent_admin_tokens_token ON agent_admin_tokens(token);
|
CREATE INDEX IF NOT EXISTS idx_agent_admin_tokens_token ON agent_admin_tokens(token);
|
||||||
CREATE INDEX IF NOT EXISTS idx_agent_admin_tokens_expires ON agent_admin_tokens(expires_at);
|
CREATE INDEX IF NOT EXISTS idx_agent_admin_tokens_expires ON agent_admin_tokens(expires_at);
|
||||||
|
|
||||||
-- 5. 创建 agent_models 表
|
-- 6. 创建 agent_mcp_servers 表 (agent_models 表已废弃,模型管理已迁移到 New API)
|
||||||
CREATE TABLE IF NOT EXISTS agent_models (
|
|
||||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
||||||
name VARCHAR(255) NOT NULL,
|
|
||||||
provider VARCHAR(100) NOT NULL,
|
|
||||||
model VARCHAR(255) NOT NULL,
|
|
||||||
server VARCHAR(500),
|
|
||||||
api_key VARCHAR(500),
|
|
||||||
is_default BOOLEAN DEFAULT FALSE,
|
|
||||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
||||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
||||||
);
|
|
||||||
|
|
||||||
-- agent_models 索引
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_agent_models_is_default ON agent_models(is_default);
|
|
||||||
|
|
||||||
-- 6. 创建 agent_mcp_servers 表
|
|
||||||
CREATE TABLE IF NOT EXISTS agent_mcp_servers (
|
CREATE TABLE IF NOT EXISTS agent_mcp_servers (
|
||||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
bot_id UUID REFERENCES agent_bots(id) ON DELETE CASCADE,
|
bot_id UUID REFERENCES agent_bots(id) ON DELETE CASCADE,
|
||||||
|
|||||||
@ -1832,13 +1832,7 @@
|
|||||||
<div class="settings-tab-content active" data-tab="basic">
|
<div class="settings-tab-content active" data-tab="basic">
|
||||||
<div class="settings-grid">
|
<div class="settings-grid">
|
||||||
<div class="settings-group">
|
<div class="settings-group">
|
||||||
<div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px;">
|
<label class="settings-label" for="model-select">模型</label>
|
||||||
<label class="settings-label" for="model-select" style="margin-bottom: 0;">模型</label>
|
|
||||||
<a href="model-manager.html" style="font-size: 12px; color: var(--primary); text-decoration: none; display: flex; align-items: center; gap: 4px;">
|
|
||||||
<i data-lucide="settings" style="width: 12px; height: 12px;"></i>
|
|
||||||
管理模型
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<select id="model-select" class="settings-select">
|
<select id="model-select" class="settings-select">
|
||||||
<option value="">选择模型...</option>
|
<option value="">选择模型...</option>
|
||||||
<!-- 动态生成 -->
|
<!-- 动态生成 -->
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -362,38 +362,7 @@ class UserSearchResponse(BaseModel):
|
|||||||
email: Optional[str] = None
|
email: Optional[str] = None
|
||||||
|
|
||||||
|
|
||||||
# --- 模型相关 ---
|
# --- 模型相关(已废弃,模型管理已迁移到 New API)---
|
||||||
class ModelCreate(BaseModel):
|
|
||||||
"""创建模型请求"""
|
|
||||||
name: str
|
|
||||||
provider: str
|
|
||||||
model: str
|
|
||||||
server: Optional[str] = None
|
|
||||||
api_key: Optional[str] = None
|
|
||||||
is_default: bool = False
|
|
||||||
|
|
||||||
|
|
||||||
class ModelUpdate(BaseModel):
|
|
||||||
"""更新模型请求"""
|
|
||||||
name: Optional[str] = None
|
|
||||||
provider: Optional[str] = None
|
|
||||||
model: Optional[str] = None
|
|
||||||
server: Optional[str] = None
|
|
||||||
api_key: Optional[str] = None
|
|
||||||
is_default: Optional[bool] = None
|
|
||||||
|
|
||||||
|
|
||||||
class ModelResponse(BaseModel):
|
|
||||||
"""模型响应"""
|
|
||||||
id: str
|
|
||||||
name: str
|
|
||||||
provider: str
|
|
||||||
model: str
|
|
||||||
server: Optional[str]
|
|
||||||
api_key: Optional[str] # 掩码显示
|
|
||||||
is_default: bool
|
|
||||||
created_at: str
|
|
||||||
updated_at: str
|
|
||||||
|
|
||||||
|
|
||||||
# --- Bot 相关 ---
|
# --- Bot 相关 ---
|
||||||
@ -1001,22 +970,7 @@ async def init_bot_manager_tables():
|
|||||||
"CREATE INDEX IF NOT EXISTS idx_agent_admin_tokens_token ON agent_admin_tokens(token)",
|
"CREATE INDEX IF NOT EXISTS idx_agent_admin_tokens_token ON agent_admin_tokens(token)",
|
||||||
"CREATE INDEX IF NOT EXISTS idx_agent_admin_tokens_expires ON agent_admin_tokens(expires_at)",
|
"CREATE INDEX IF NOT EXISTS idx_agent_admin_tokens_expires ON agent_admin_tokens(expires_at)",
|
||||||
|
|
||||||
# models 表
|
# agent_models 表已废弃,模型管理已迁移到 New API
|
||||||
"""
|
|
||||||
CREATE TABLE IF NOT EXISTS agent_models (
|
|
||||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
||||||
name VARCHAR(255) NOT NULL,
|
|
||||||
provider VARCHAR(100) NOT NULL,
|
|
||||||
model VARCHAR(255) NOT NULL,
|
|
||||||
server VARCHAR(500),
|
|
||||||
api_key VARCHAR(500),
|
|
||||||
is_default BOOLEAN DEFAULT FALSE,
|
|
||||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
||||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
||||||
)
|
|
||||||
""",
|
|
||||||
# models 索引
|
|
||||||
"CREATE INDEX IF NOT EXISTS idx_agent_models_is_default ON agent_models(is_default)",
|
|
||||||
|
|
||||||
# bots 表(合并 settings 为 JSONB 字段)
|
# bots 表(合并 settings 为 JSONB 字段)
|
||||||
"""
|
"""
|
||||||
@ -1094,250 +1048,14 @@ def datetime_to_str(dt: datetime) -> str:
|
|||||||
return dt.isoformat() if dt else ""
|
return dt.isoformat() if dt else ""
|
||||||
|
|
||||||
|
|
||||||
# ============== 模型管理 API ==============
|
# ============== 模型管理 API(已废弃,已迁移到 New API)=============
|
||||||
|
|
||||||
@router.get("/api/v1/models", response_model=List[ModelResponse])
|
|
||||||
async def get_models(authorization: Optional[str] = Header(None)):
|
|
||||||
"""
|
|
||||||
获取所有模型配置
|
|
||||||
|
|
||||||
Args:
|
|
||||||
authorization: Bearer token
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
List[ModelResponse]: 模型列表
|
|
||||||
"""
|
|
||||||
verify_auth(authorization)
|
|
||||||
|
|
||||||
pool = get_db_pool_manager().pool
|
|
||||||
|
|
||||||
async with pool.connection() as conn:
|
|
||||||
async with conn.cursor() as cursor:
|
|
||||||
await cursor.execute("""
|
|
||||||
SELECT id, name, provider, model, server, api_key, is_default, created_at, updated_at
|
|
||||||
FROM agent_models
|
|
||||||
ORDER BY is_default DESC, created_at DESC
|
|
||||||
""")
|
|
||||||
rows = await cursor.fetchall()
|
|
||||||
|
|
||||||
return [
|
|
||||||
ModelResponse(
|
|
||||||
id=str(row[0]),
|
|
||||||
name=row[1],
|
|
||||||
provider=row[2],
|
|
||||||
model=row[3],
|
|
||||||
server=row[4],
|
|
||||||
api_key=mask_api_key(row[5]),
|
|
||||||
is_default=row[6],
|
|
||||||
created_at=datetime_to_str(row[7]),
|
|
||||||
updated_at=datetime_to_str(row[8])
|
|
||||||
)
|
|
||||||
for row in rows
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
@router.post("/api/v1/models", response_model=ModelResponse)
|
|
||||||
async def create_model(request: ModelCreate, authorization: Optional[str] = Header(None)):
|
|
||||||
"""
|
|
||||||
创建新模型
|
|
||||||
|
|
||||||
Args:
|
|
||||||
request: 模型创建请求
|
|
||||||
authorization: Bearer token
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
ModelResponse: 创建的模型信息
|
|
||||||
"""
|
|
||||||
verify_auth(authorization)
|
|
||||||
|
|
||||||
pool = get_db_pool_manager().pool
|
|
||||||
|
|
||||||
# 如果设置为默认,需要先取消其他默认模型
|
|
||||||
if request.is_default:
|
|
||||||
async with pool.connection() as conn:
|
|
||||||
async with conn.cursor() as cursor:
|
|
||||||
await cursor.execute("UPDATE agent_models SET is_default = FALSE WHERE is_default = TRUE")
|
|
||||||
await conn.commit()
|
|
||||||
|
|
||||||
async with pool.connection() as conn:
|
|
||||||
async with conn.cursor() as cursor:
|
|
||||||
await cursor.execute("""
|
|
||||||
INSERT INTO agent_models (name, provider, model, server, api_key, is_default)
|
|
||||||
VALUES (%s, %s, %s, %s, %s, %s)
|
|
||||||
RETURNING id, created_at, updated_at
|
|
||||||
""", (
|
|
||||||
request.name,
|
|
||||||
request.provider,
|
|
||||||
request.model,
|
|
||||||
request.server,
|
|
||||||
request.api_key,
|
|
||||||
request.is_default
|
|
||||||
))
|
|
||||||
row = await cursor.fetchone()
|
|
||||||
await conn.commit()
|
|
||||||
|
|
||||||
return ModelResponse(
|
|
||||||
id=str(row[0]),
|
|
||||||
name=request.name,
|
|
||||||
provider=request.provider,
|
|
||||||
model=request.model,
|
|
||||||
server=request.server,
|
|
||||||
api_key=mask_api_key(request.api_key),
|
|
||||||
is_default=request.is_default,
|
|
||||||
created_at=datetime_to_str(row[1]),
|
|
||||||
updated_at=datetime_to_str(row[2])
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@router.put("/api/v1/models/{model_id}", response_model=ModelResponse)
|
|
||||||
async def update_model(
|
|
||||||
model_id: str,
|
|
||||||
request: ModelUpdate,
|
|
||||||
authorization: Optional[str] = Header(None)
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
更新模型
|
|
||||||
|
|
||||||
Args:
|
|
||||||
model_id: 模型 ID
|
|
||||||
request: 模型更新请求
|
|
||||||
authorization: Bearer token
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
ModelResponse: 更新后的模型信息
|
|
||||||
"""
|
|
||||||
verify_auth(authorization)
|
|
||||||
|
|
||||||
pool = get_db_pool_manager().pool
|
|
||||||
|
|
||||||
# 构建更新字段
|
|
||||||
update_fields = []
|
|
||||||
values = []
|
|
||||||
|
|
||||||
if request.name is not None:
|
|
||||||
update_fields.append("name = %s")
|
|
||||||
values.append(request.name)
|
|
||||||
if request.provider is not None:
|
|
||||||
update_fields.append("provider = %s")
|
|
||||||
values.append(request.provider)
|
|
||||||
if request.model is not None:
|
|
||||||
update_fields.append("model = %s")
|
|
||||||
values.append(request.model)
|
|
||||||
if request.server is not None:
|
|
||||||
update_fields.append("server = %s")
|
|
||||||
values.append(request.server)
|
|
||||||
if request.api_key is not None:
|
|
||||||
update_fields.append("api_key = %s")
|
|
||||||
values.append(request.api_key)
|
|
||||||
if request.is_default is not None:
|
|
||||||
update_fields.append("is_default = %s")
|
|
||||||
values.append(request.is_default)
|
|
||||||
|
|
||||||
if not update_fields:
|
|
||||||
raise HTTPException(status_code=400, detail="No fields to update")
|
|
||||||
|
|
||||||
update_fields.append("updated_at = NOW()")
|
|
||||||
values.append(model_id)
|
|
||||||
|
|
||||||
# 如果设置为默认,需要先取消其他默认模型
|
|
||||||
if request.is_default is True:
|
|
||||||
async with pool.connection() as conn:
|
|
||||||
async with conn.cursor() as cursor:
|
|
||||||
await cursor.execute("UPDATE agent_models SET is_default = FALSE WHERE is_default = TRUE")
|
|
||||||
await conn.commit()
|
|
||||||
|
|
||||||
async with pool.connection() as conn:
|
|
||||||
async with conn.cursor() as cursor:
|
|
||||||
await cursor.execute(f"""
|
|
||||||
UPDATE agent_models
|
|
||||||
SET {', '.join(update_fields)}
|
|
||||||
WHERE id = %s
|
|
||||||
RETURNING id, name, provider, model, server, api_key, is_default, created_at, updated_at
|
|
||||||
""", values)
|
|
||||||
row = await cursor.fetchone()
|
|
||||||
|
|
||||||
if not row:
|
|
||||||
raise HTTPException(status_code=404, detail="Model not found")
|
|
||||||
|
|
||||||
await conn.commit()
|
|
||||||
|
|
||||||
return ModelResponse(
|
|
||||||
id=str(row[0]),
|
|
||||||
name=row[1],
|
|
||||||
provider=row[2],
|
|
||||||
model=row[3],
|
|
||||||
server=row[4],
|
|
||||||
api_key=mask_api_key(row[5]),
|
|
||||||
is_default=row[6],
|
|
||||||
created_at=datetime_to_str(row[7]),
|
|
||||||
updated_at=datetime_to_str(row[8])
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@router.delete("/api/v1/models/{model_id}", response_model=SuccessResponse)
|
|
||||||
async def delete_model(model_id: str, authorization: Optional[str] = Header(None)):
|
|
||||||
"""
|
|
||||||
删除模型
|
|
||||||
|
|
||||||
Args:
|
|
||||||
model_id: 模型 ID
|
|
||||||
authorization: Bearer token
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
SuccessResponse: 删除结果
|
|
||||||
"""
|
|
||||||
verify_auth(authorization)
|
|
||||||
|
|
||||||
pool = get_db_pool_manager().pool
|
|
||||||
|
|
||||||
async with pool.connection() as conn:
|
|
||||||
async with conn.cursor() as cursor:
|
|
||||||
await cursor.execute("DELETE FROM agent_models WHERE id = %s RETURNING id", (model_id,))
|
|
||||||
row = await cursor.fetchone()
|
|
||||||
|
|
||||||
if not row:
|
|
||||||
raise HTTPException(status_code=404, detail="Model not found")
|
|
||||||
|
|
||||||
await conn.commit()
|
|
||||||
|
|
||||||
return SuccessResponse(success=True, message="Model deleted successfully")
|
|
||||||
|
|
||||||
|
|
||||||
@router.patch("/api/v1/models/{model_id}/default", response_model=SuccessResponse)
|
|
||||||
async def set_default_model(model_id: str, authorization: Optional[str] = Header(None)):
|
|
||||||
"""
|
|
||||||
设置默认模型
|
|
||||||
|
|
||||||
Args:
|
|
||||||
model_id: 模型 ID
|
|
||||||
authorization: Bearer token
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
SuccessResponse: 设置结果
|
|
||||||
"""
|
|
||||||
verify_auth(authorization)
|
|
||||||
|
|
||||||
pool = get_db_pool_manager().pool
|
|
||||||
|
|
||||||
# 首先检查模型是否存在
|
|
||||||
async with pool.connection() as conn:
|
|
||||||
async with conn.cursor() as cursor:
|
|
||||||
await cursor.execute("SELECT id FROM agent_models WHERE id = %s", (model_id,))
|
|
||||||
row = await cursor.fetchone()
|
|
||||||
|
|
||||||
if not row:
|
|
||||||
raise HTTPException(status_code=404, detail="Model not found")
|
|
||||||
|
|
||||||
# 取消所有默认设置
|
|
||||||
await cursor.execute("UPDATE agent_models SET is_default = FALSE WHERE is_default = TRUE")
|
|
||||||
|
|
||||||
# 设置新的默认模型
|
|
||||||
await cursor.execute("UPDATE agent_models SET is_default = TRUE WHERE id = %s", (model_id,))
|
|
||||||
|
|
||||||
await conn.commit()
|
|
||||||
|
|
||||||
return SuccessResponse(success=True, message="Default model updated successfully")
|
|
||||||
|
|
||||||
|
# 以下模型管理接口已被移除,现在使用 /api/v1/newapi/models 从 New API 获取模型列表
|
||||||
|
# - GET /api/v1/models
|
||||||
|
# - POST /api/v1/models
|
||||||
|
# - PUT /api/v1/models/{model_id}
|
||||||
|
# - DELETE /api/v1/models/{model_id}
|
||||||
|
# - PATCH /api/v1/models/{model_id}/default
|
||||||
|
|
||||||
# ============== Bot 管理 API ==============
|
# ============== Bot 管理 API ==============
|
||||||
|
|
||||||
@ -2441,7 +2159,7 @@ async def user_login(request: UserLoginRequest):
|
|||||||
SET new_api_session = %s, new_api_user_id = %s, new_api_token = %s
|
SET new_api_session = %s, new_api_user_id = %s, new_api_token = %s
|
||||||
WHERE id = %s
|
WHERE id = %s
|
||||||
""", (new_api_session, new_api_user_id, new_api_token, user_id))
|
""", (new_api_session, new_api_user_id, new_api_token, user_id))
|
||||||
logger.info(f"Stored New API session, user_id and token for user {username}")
|
logger.info(f"Stored New API session, user_id and token for user {username} token: {new_api_token}")
|
||||||
else:
|
else:
|
||||||
logger.warning(f"New API login succeeded but no session/user_id. Response: {login_result}")
|
logger.warning(f"New API login succeeded but no session/user_id. Response: {login_result}")
|
||||||
else:
|
else:
|
||||||
|
|||||||
@ -347,9 +347,9 @@ class NewAPIProxy:
|
|||||||
"""获取或创建令牌(如果没有则创建一个)"""
|
"""获取或创建令牌(如果没有则创建一个)"""
|
||||||
# 先尝试获取现有令牌
|
# 先尝试获取现有令牌
|
||||||
tokens_result = await self.get_tokens(cookies, new_api_user_id)
|
tokens_result = await self.get_tokens(cookies, new_api_user_id)
|
||||||
|
|
||||||
if tokens_result.get("success") and tokens_result.get("data"):
|
if tokens_result.get("success") and tokens_result.get("data"):
|
||||||
tokens = tokens_result["data"]
|
# data 格式: {'page': 1, 'page_size': 100, 'total': 4, 'items': [...]}
|
||||||
|
tokens = tokens_result["data"].get("items", [])
|
||||||
if isinstance(tokens, list) and len(tokens) > 0:
|
if isinstance(tokens, list) and len(tokens) > 0:
|
||||||
# 返回第一个可用的令牌
|
# 返回第一个可用的令牌
|
||||||
return {
|
return {
|
||||||
@ -364,13 +364,17 @@ class NewAPIProxy:
|
|||||||
new_api_user_id,
|
new_api_user_id,
|
||||||
name=token_name
|
name=token_name
|
||||||
)
|
)
|
||||||
|
|
||||||
if create_result.get("success"):
|
if create_result.get("success"):
|
||||||
return {
|
# 创建成功后重新获取令牌列表
|
||||||
"success": True,
|
tokens_result = await self.get_tokens(cookies, new_api_user_id)
|
||||||
"data": create_result.get("data"),
|
if tokens_result.get("success") and tokens_result.get("data"):
|
||||||
"message": "已创建新令牌"
|
tokens = tokens_result["data"].get("items", [])
|
||||||
}
|
if isinstance(tokens, list) and len(tokens) > 0:
|
||||||
|
return {
|
||||||
|
"success": True,
|
||||||
|
"data": tokens[0],
|
||||||
|
"message": "已创建新令牌"
|
||||||
|
}
|
||||||
|
|
||||||
return create_result
|
return create_result
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user