feat: Tree CRUD APIs - dir_create/delete/list

This commit is contained in:
yumoqing 2026-07-22 18:31:38 +08:00
parent bc4289efc8
commit 7af39b0737
2 changed files with 70 additions and 1 deletions

View File

@ -52,7 +52,10 @@
{"leading": "/api/engines", "registerfunction": "engines"},
{"leading": "/api/search", "registerfunction": "search"},
{"leading": "/api/doc/upload", "registerfunction": "doc_upload"},
{"leading": "/api/doc/delete", "registerfunction": "doc_delete"}
{"leading": "/api/doc/delete", "registerfunction": "doc_delete"},
{"leading": "/api/dir/create", "registerfunction": "dir_create"},
{"leading": "/api/dir/delete", "registerfunction": "dir_delete"},
{"leading": "/api/dir/list", "registerfunction": "dir_list"}
]
},
"hot_reload": true

66
init.py
View File

@ -242,6 +242,69 @@ def _call_graph(path, data, timeout=10):
return json.loads(resp.read())
async def dir_create_handler(request, params_kw, *args, **kwargs):
"""创建目录"""
env = request._run_ns
try:
kb_id = params_kw.get("kb_id", "")
parent_id = params_kw.get("parent_id", "")
dir_name = params_kw.get("dir_name", "")
if not kb_id or not dir_name:
return json.dumps({"error": "kb_id and dir_name required"})
async with get_sor_context(env, 'rag') as sor:
dir_id = uuid.uuid4().hex[:16]
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})
return json.dumps({"status": "SUCCEEDED", "dir_id": dir_id})
except Exception as e:
exception(f"dir_create: {e}")
return json.dumps({"error": str(e)})
async def dir_delete_handler(request, params_kw, *args, **kwargs):
"""删除目录/文件"""
env = request._run_ns
try:
item_id = params_kw.get("item_id", "")
if not item_id:
return json.dumps({"error": "item_id required"})
async with get_sor_context(env, 'rag') as sor:
await sor.sqlExe("DELETE FROM document_chunks WHERE id=${id}$ OR doc_id=${id}$", {"id": item_id})
return json.dumps({"status": "SUCCEEDED"})
except Exception as e:
exception(f"dir_delete: {e}")
return json.dumps({"error": str(e)})
async def dir_list_handler(request, params_kw, *args, **kwargs):
"""列出知识库的目录树"""
env = request._run_ns
try:
kb_id = params_kw.get("kb_id", "")
if not kb_id:
return json.dumps({"error": "kb_id required"})
async with get_sor_context(env, 'rag') as sor:
# Get directories (chunk_type='directory')
dirs = await sor.sqlExe(
"SELECT id, content as label, description as parent_id FROM document_chunks WHERE kb_id=${kb_id}$ AND chunk_type='directory'",
{"kb_id": kb_id})
# Get files (documents table)
docs = await sor.sqlExe(
"SELECT id, file_name as label, '' as parent_id FROM documents WHERE kb_id=${kb_id}$",
{"kb_id": kb_id})
items = []
for d in dirs:
items.append({"id": d.id, "label": d.label, "parent_id": d.parent_id or "", "type": "dir"})
for d in docs:
items.append({"id": d.id, "label": d.label, "parent_id": "", "type": "file"})
return json.dumps({"status": "SUCCEEDED", "items": items})
except Exception as e:
exception(f"dir_list: {e}")
return json.dumps({"error": str(e)})
def init_ragserver():
env = ServerEnv()
rf = RegisterFunction()
@ -251,3 +314,6 @@ def init_ragserver():
rf.register("search", search_handler)
rf.register("doc_upload", doc_upload_handler)
rf.register("doc_delete", doc_delete_handler)
rf.register("dir_create", dir_create_handler)
rf.register("dir_delete", dir_delete_handler)
rf.register("dir_list", dir_list_handler)