fix: api/kb/list returns widget JSON, remove broken dspy files

This commit is contained in:
yumoqing 2026-07-22 18:44:38 +08:00
parent 95c71a9b88
commit f923f6cceb
4 changed files with 26 additions and 108 deletions

21
init.py
View File

@ -24,8 +24,25 @@ async def kb_list_handler(request, params_kw, *args, **kwargs):
userorgid = await env.get_userorgid()
async with get_sor_context(env, 'rag') as sor:
recs = await sor.R("knowledge_bases", {"org_id": userorgid})
rows = [dict(r) for r in recs]
return json.dumps({"status": "SUCCEEDED", "data": {"rows": rows, "total": len(rows)}}, ensure_ascii=False, default=str)
cards = []
for r in recs:
doc_recs = await sor.R("documents", {"kb_id": r.id})
doc_count = len(doc_recs)
total_size = r.total_size or 0
size_str = f"{total_size/1024:.0f}KB" if total_size else "0B"
engine = r.embedding_engine or "CLIP"
card = {"widgettype":"VBox","options":{"cwidth":16,"cheight":12,"bgcolor":"#f0f7ff","padding":"16px","css":"card clickable","border":"1px solid #d0e4f7"},"subwidgets":[
{"widgettype":"Text","options":{"text":"📚 " + str(r.name),"cfontsize":16,"fontWeight":"bold"}},
{"widgettype":"Text","options":{"text":str(engine)+" · 1024维","cfontsize":12,"color":"#888"}},
{"widgettype":"HBox","options":{"spacing":"12px"},"subwidgets":[
{"widgettype":"Text","options":{"text":"📄 "+str(doc_count)+"文档","cfontsize":12,"color":"#666"}},
{"widgettype":"Text","options":{"text":"💾 "+size_str,"cfontsize":12,"color":"#666"}}]}],
"binds":[{"wid":"self","event":"click","actiontype":"urlwidget","target":"app.rag_main_content","mode":"replace","options":{"url":"/knowledge_bases_list/detail.ui"}}]}
cards.append(card)
if not cards:
cards.append({"widgettype":"Text","options":{"text":"暂无知识库","color":"#aaa","cfontsize":14,"halign":"center"}})
result = {"widgettype":"HBox","options":{"width":"100%","spacing":"12px","wrap":True},"subwidgets":cards}
return json.dumps(result, ensure_ascii=False)
except Exception as e:
exception(f"kb_list: {e}, {format_exc()}")
return json.dumps({"error": str(e)})

View File

@ -1,46 +0,0 @@
import asyncio
async def _do():
env = request._run_ns
userorgid = await env.get_userorgid()
cards = []
async with get_sor_context(env, 'rag') as sor:
recs = await sor.R("knowledge_bases", {"org_id": userorgid})
for r in recs:
doc_recs = await sor.R("documents", {"kb_id": r.id})
doc_count = len(doc_recs)
total_size = r.total_size or 0
if total_size > 1073741824:
size_str = f"{total_size/1073741824:.1f}GB"
elif total_size > 1048576:
size_str = f"{total_size/1048576:.0f}MB"
else:
size_str = f"{total_size/1024:.0f}KB"
engine = r.embedding_engine or "CLIP"
card = {
"widgettype": "VBox",
"options": {
"cwidth": 16, "cheight": 12, "bgcolor": "#f0f7ff",
"padding": "16px", "css": "card clickable",
"border": "1px solid #d0e4f7"
},
"subwidgets": [
{"widgettype": "Text", "options": {"text": "📚 " + str(r.name), "cfontsize": 16, "fontWeight": "bold"}},
{"widgettype": "Text", "options": {"text": str(engine) + " · 1024维", "cfontsize": 12, "color": "#888"}},
{"widgettype": "HBox", "options": {"spacing": "12px"}, "subwidgets": [
{"widgettype": "Text", "options": {"text": "📄 " + str(doc_count) + "文档", "cfontsize": 12, "color": "#666"}},
{"widgettype": "Text", "options": {"text": "💾 " + size_str, "cfontsize": 12, "color": "#666"}}
]}
],
"binds": [{"wid": "self", "event": "click", "actiontype": "urlwidget",
"target": "app.rag_main_content", "mode": "replace",
"options": {"url": entire_url('/knowledge_bases_list/detail.ui')}}]
}
cards.append(card)
return {
"widgettype": "HBox",
"options": {"width": "100%", "spacing": "12px", "wrap": True},
"subwidgets": cards
}
result = asyncio.get_event_loop().run_until_complete(_do())

View File

@ -9,30 +9,19 @@
"subwidgets": [
{
"widgettype": "HBox",
"options": {
"width": "100%",
"justifyContent": "space-between",
"alignItems": "center"
},
"options": {"width": "100%", "justifyContent": "space-between", "alignItems": "center"},
"subwidgets": [
{
"widgettype": "VBox",
"options": {"spacing": "4px"},
"subwidgets": [
{"widgettype": "Text", "options": {"text": "知识库", "cfontsize": 22, "fontWeight": "bold", "color": "#333"}},
{"widgettype": "Text", "options": {"text": "点击知识库进入文档管理,支持多级目录和拖拽上传", "cfontsize": 14, "color": "#888"}}
]
},
{
"widgettype": "Button",
"options": {"label": "+ 新建知识库", "bgcolor": "#4a90d9", "color": "#fff"}
}
{"widgettype": "VBox", "options": {"spacing": "4px"}, "subwidgets": [
{"widgettype": "Text", "options": {"text": "知识库", "cfontsize": 22, "fontWeight": "bold", "color": "#333"}},
{"widgettype": "Text", "options": {"text": "点击知识库进入文档管理,支持多级目录和拖拽上传", "cfontsize": 14, "color": "#888"}}
]},
{"widgettype": "Button", "options": {"label": "+ 新建知识库", "bgcolor": "#4a90d9", "color": "#fff"}}
]
},
{
"widgettype": "urlwidget",
"options": {
"url": "{{entire_url('/knowledge_bases_list/get_kb_cards.dspy')}}"
"url": "{{entire_url('/api/kb/list')}}"
}
}
]

View File

@ -1,42 +0,0 @@
import asyncio
async def _do():
action = params_kw.get("action", "")
kb_id = params_kw.get("kb_id", "")
env = request._run_ns
folder_label = params_kw.get("folder_label", "")
if action == "create_dir":
dir_name = params_kw.get("dir_name", "")
parent_id = params_kw.get("parent_id", "")
if dir_name:
async with get_sor_context(env, 'rag') as sor:
dir_id = "dir_" + str(abs(hash(dir_name + parent_id)))[:12]
await sor.sqlExe(
"INSERT INTO document_chunks (id, doc_id, kb_id, chunk_index, chunk_type, content, description, created_at) "
"VALUES (${id}$, '', ${kb_id}$, 0, 'directory', ${name}$, ${parent}$, NOW())",
{"id": dir_id, "kb_id": kb_id, "name": dir_name, "parent": parent_id})
folder_label = folder_label or dir_name
elif action == "delete_item":
item_id = params_kw.get("item_id", "")
if item_id:
async with get_sor_context(env, 'rag') as sor:
await sor.sqlExe("DELETE FROM document_chunks WHERE id=${id}$", {"id": item_id})
return {
"widgettype": "VBox",
"options": {"spacing": "12px"},
"subwidgets": [
{
"widgettype": "HBox",
"options": {"spacing": "4px"},
"subwidgets": [
{"widgettype": "Text", "options": {"text": "📂 " + str(folder_label), "cfontsize": 16, "fontWeight": "bold", "color": "#333"}},
{"widgettype": "Text", "options": {"text": "操作成功", "cfontsize": 12, "color": "#50b86c"}}
]
}
]
}
result = asyncio.get_event_loop().run_until_complete(_do())