Agent Builder: SQLite-taulu + REST API (GET/POST/DELETE)

- DB skeemaversio 3: agents-taulu (id, name, avatar, role, model, color,
  docs, prompt, temperature, top_k, max_tokens, repetition_penalty)
- CRUD: upsert_agent, get_agents, delete_agent
- API: GET/POST /api/v1/agents, DELETE /api/v1/agents/:id
- Oletusagentteja (is_default=1) ei voi poistaa

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-08 10:43:22 +03:00
parent 8a5f1b753c
commit 21aac49a52
2 changed files with 129 additions and 0 deletions

View File

@@ -387,6 +387,8 @@ async fn main() {
.route("/api/v1/model", axum::routing::post(api_change_model))
.route("/api/v1/hardware", get(api_hardware))
.route("/api/v1/ollama/tags", get(api_ollama_tags))
.route("/api/v1/agents", get(api_get_agents).post(api_upsert_agent))
.route("/api/v1/agents/:id", axum::routing::delete(api_delete_agent))
.route("/admin", get(admin_page))
.nest_service("/", {
let static_dir = std::env::var("STATIC_DIR").unwrap_or_else(|_| "../static".to_string());
@@ -462,6 +464,34 @@ fn admin_unauthorized() -> axum::response::Response {
.unwrap()
}
// ── Agents API ──
async fn api_get_agents(
axum::extract::State(state): axum::extract::State<Arc<AppState>>,
) -> axum::response::Response {
axum::Json(state.db.get_agents()).into_response()
}
async fn api_upsert_agent(
axum::extract::State(state): axum::extract::State<Arc<AppState>>,
axum::Json(payload): axum::Json<serde_json::Value>,
) -> axum::response::Response {
match state.db.upsert_agent(&payload) {
Ok(()) => axum::Json(serde_json::json!({"ok": true})).into_response(),
Err(e) => (axum::http::StatusCode::BAD_REQUEST, e).into_response(),
}
}
async fn api_delete_agent(
axum::extract::State(state): axum::extract::State<Arc<AppState>>,
axum::extract::Path(id): axum::extract::Path<String>,
) -> axum::response::Response {
match state.db.delete_agent(&id) {
Ok(()) => axum::Json(serde_json::json!({"ok": true})).into_response(),
Err(e) => (axum::http::StatusCode::BAD_REQUEST, e).into_response(),
}
}
async fn admin_page(headers: axum::http::HeaderMap) -> axum::response::Response {
if !check_admin_auth(&headers) { return admin_unauthorized(); }
axum::response::Html(ADMIN_HTML).into_response()