mirror of
https://github.com/hoshikawa2/rfp_response_automation.git
synced 2026-03-03 16:09:35 +00:00
160 lines
3.9 KiB
Python
160 lines
3.9 KiB
Python
from flask import Blueprint, render_template, request, jsonify, redirect, flash
|
|
from modules.core.security import requires_admin_auth
|
|
from modules.core.audit import audit_log
|
|
import threading
|
|
from modules.core.audit import audit_log
|
|
|
|
from oci_genai_llm_graphrag_rerank_rfp import (
|
|
search_chunks_for_invalidation,
|
|
revoke_chunk_by_hash,
|
|
get_chunk_metadata,
|
|
add_manual_knowledge_entry,
|
|
reload_all
|
|
)
|
|
|
|
admin_bp = Blueprint("admin", __name__)
|
|
|
|
|
|
# =========================
|
|
# ADMIN HOME (invalidate UI)
|
|
# =========================
|
|
@admin_bp.route("/")
|
|
@requires_admin_auth
|
|
def admin_home():
|
|
return render_template("admin_menu.html")
|
|
|
|
@admin_bp.route("/invalidate")
|
|
@requires_admin_auth
|
|
def invalidate_page():
|
|
return render_template(
|
|
"invalidate.html",
|
|
results=[],
|
|
statement=""
|
|
)
|
|
|
|
# =========================
|
|
# SEARCH CHUNKS
|
|
# =========================
|
|
@admin_bp.route("/search", methods=["POST"])
|
|
@requires_admin_auth
|
|
def search_for_invalidation():
|
|
|
|
statement = request.form["statement"]
|
|
|
|
docs = search_chunks_for_invalidation(statement)
|
|
|
|
hashes = [d.metadata.get("chunk_hash") for d in docs if d.metadata.get("chunk_hash")]
|
|
meta = get_chunk_metadata(hashes)
|
|
|
|
results = []
|
|
|
|
for d in docs:
|
|
h = d.metadata.get("chunk_hash")
|
|
m = meta.get(h, {})
|
|
|
|
results.append({
|
|
"chunk_hash": h,
|
|
"source": d.metadata.get("source"),
|
|
"text": d.page_content,
|
|
"origin": m.get("origin"),
|
|
"status": m.get("status")
|
|
})
|
|
|
|
return render_template(
|
|
"invalidate.html",
|
|
statement=statement,
|
|
results=results
|
|
)
|
|
|
|
|
|
# =========================
|
|
# REVOKE
|
|
# =========================
|
|
@admin_bp.route("/revoke", methods=["POST"])
|
|
@requires_admin_auth
|
|
def revoke_chunk_ui():
|
|
|
|
data = request.get_json()
|
|
|
|
chunk_hash = str(data["chunk_hash"])
|
|
reason = str(data.get("reason", "Manual revoke"))
|
|
audit_log("INVALIDATE", f"chunk_hash={chunk_hash}")
|
|
|
|
print("chunk_hash", chunk_hash)
|
|
print("reason", reason)
|
|
|
|
revoke_chunk_by_hash(chunk_hash, reason)
|
|
|
|
return {"status": "ok", "chunk_hash": chunk_hash}
|
|
|
|
|
|
# =========================
|
|
# ADD MANUAL KNOWLEDGE
|
|
# =========================
|
|
@admin_bp.route("/add-knowledge", methods=["POST"])
|
|
@requires_admin_auth
|
|
def add_manual_knowledge():
|
|
|
|
data = request.get_json(force=True)
|
|
|
|
chunk_hash = add_manual_knowledge_entry(
|
|
text=data["text"],
|
|
author="ADMIN",
|
|
reason=data.get("reason"),
|
|
source="MANUAL_INPUT",
|
|
origin="MANUAL",
|
|
also_update_graph=True
|
|
)
|
|
audit_log("ADD_KNOWLEDGE", f"chunk_hash={chunk_hash}")
|
|
|
|
return jsonify({
|
|
"status": "OK",
|
|
"chunk_hash": chunk_hash
|
|
})
|
|
|
|
# =========================
|
|
# UPDATE CHUNK
|
|
# =========================
|
|
@admin_bp.route("/update-chunk", methods=["POST"])
|
|
@requires_admin_auth
|
|
def update_chunk():
|
|
|
|
data = request.get_json() or {}
|
|
|
|
chunk_hash = str(data.get("chunk_hash", "")).strip()
|
|
text = str(data.get("text", "")).strip()
|
|
|
|
print("chunk_hash", chunk_hash)
|
|
print("text", text)
|
|
|
|
if not chunk_hash:
|
|
return {"status": "error", "message": "missing hash"}, 400
|
|
|
|
reason = str(data.get("reason", "Manual change"))
|
|
|
|
revoke_chunk_by_hash(chunk_hash, reason=reason)
|
|
chunk_hash = add_manual_knowledge_entry(
|
|
text=text,
|
|
author="ADMIN",
|
|
reason=reason,
|
|
source="MANUAL_INPUT",
|
|
origin="MANUAL",
|
|
also_update_graph=True
|
|
)
|
|
audit_log("UPDATE CHUNK", f"chunk_hash={chunk_hash}")
|
|
|
|
return jsonify({
|
|
"status": "OK",
|
|
"chunk_hash": chunk_hash
|
|
})
|
|
|
|
@admin_bp.route("/reboot", methods=["POST"])
|
|
@requires_admin_auth
|
|
def reboot_service():
|
|
# roda em background pra não travar request
|
|
threading.Thread(target=reload_all, daemon=True).start()
|
|
|
|
return jsonify({
|
|
"status": "ok",
|
|
"message": "Knowledge reload started"
|
|
}) |