feat(saas): extend agent templates with soul_content, add /available endpoint, key pool cleanup, and industry seed templates

- Add 9 extended fields to AgentTemplateInfo: soul_content, scenarios,
  welcome_message, quick_commands, personality, communication_style,
  emoji, version, source_id
- Refactor service.rs to use sqlx::Row (manual column extraction) to
  avoid the 16-element tuple FromRow limit
- Add /api/v1/agent-templates/available (lightweight public listing)
  and /api/v1/agent-templates/:id/full endpoints
- Add 24h key_usage_window cleanup task in scheduler
- Update seed data with extended fields for all 5 existing templates
  plus new Medical Assistant template (healthcare category)
This commit is contained in:
iven
2026-03-31 02:58:09 +08:00
parent eb956d0dce
commit 3e57fadfc9
7 changed files with 340 additions and 59 deletions

View File

@@ -34,6 +34,8 @@ pub async fn create_template(
let visibility = req.visibility.as_deref().unwrap_or("public");
let tools = req.tools.as_deref().unwrap_or(&[]);
let capabilities = req.capabilities.as_deref().unwrap_or(&[]);
let scenarios = req.scenarios.as_deref().unwrap_or(&[]);
let quick_commands = req.quick_commands.as_deref().unwrap_or(&[]);
let result = service::create_template(
&state.db, &req.name, req.description.as_deref(),
@@ -41,6 +43,14 @@ pub async fn create_template(
req.system_prompt.as_deref(),
tools, capabilities,
req.temperature, req.max_tokens, visibility,
req.soul_content.as_deref(),
Some(scenarios),
req.welcome_message.as_deref(),
Some(quick_commands),
req.personality.as_deref(),
req.communication_style.as_deref(),
req.emoji.as_deref(),
req.source_id.as_deref(),
).await?;
log_operation(&state.db, &ctx.account_id, "agent_template.create", "agent_template", &result.id,
@@ -59,6 +69,26 @@ pub async fn get_template(
Ok(Json(service::get_template(&state.db, &id).await?))
}
/// GET /api/v1/agent-templates/:id/full — 获取完整 Agent 模板(含扩展字段)
pub async fn get_full_template(
State(state): State<AppState>,
Extension(ctx): Extension<AuthContext>,
Path(id): Path<String>,
) -> SaasResult<Json<AgentTemplateInfo>> {
check_permission(&ctx, "model:read")?;
// Reuses the same get_template service which already returns all fields
Ok(Json(service::get_template(&state.db, &id).await?))
}
/// GET /api/v1/agent-templates/available — 列出公开可用模板(轻量级)
pub async fn list_available(
State(state): State<AppState>,
Extension(ctx): Extension<AuthContext>,
) -> SaasResult<Json<Vec<AvailableAgentTemplateInfo>>> {
check_permission(&ctx, "model:read")?;
Ok(Json(service::list_available(&state.db).await?))
}
/// POST /api/v1/agent-templates/:id — 更新 Agent 模板
pub async fn update_template(
State(state): State<AppState>,
@@ -79,6 +109,13 @@ pub async fn update_template(
req.max_tokens,
req.visibility.as_deref(),
req.status.as_deref(),
req.soul_content.as_deref(),
req.scenarios.as_deref(),
req.welcome_message.as_deref(),
req.quick_commands.as_deref(),
req.personality.as_deref(),
req.communication_style.as_deref(),
req.emoji.as_deref(),
).await?;
log_operation(&state.db, &ctx.account_id, "agent_template.update", "agent_template", &id,