Backend passed in codex

This commit is contained in:
Xin Wang
2026-02-08 16:10:40 +08:00
parent 3d8635670f
commit eed3ee824f
9 changed files with 309 additions and 236 deletions

View File

@@ -11,6 +11,7 @@ from ..schemas import (
KnowledgeBaseCreate, KnowledgeBaseUpdate, KnowledgeBaseOut,
KnowledgeSearchQuery, KnowledgeSearchResult, KnowledgeStats,
DocumentIndexRequest,
KnowledgeDocumentCreate,
)
from ..vector_store import (
vector_store, search_knowledge, index_document, delete_document_from_vector
@@ -25,14 +26,14 @@ def kb_to_dict(kb: KnowledgeBase) -> dict:
"user_id": kb.user_id,
"name": kb.name,
"description": kb.description,
"embedding_model": kb.embedding_model,
"chunk_size": kb.chunk_size,
"chunk_overlap": kb.chunk_overlap,
"doc_count": kb.doc_count,
"chunk_count": kb.chunk_count,
"embeddingModel": kb.embedding_model,
"chunkSize": kb.chunk_size,
"chunkOverlap": kb.chunk_overlap,
"docCount": kb.doc_count,
"chunkCount": kb.chunk_count,
"status": kb.status,
"created_at": kb.created_at.isoformat() if kb.created_at else None,
"updated_at": kb.updated_at.isoformat() if kb.updated_at else None,
"createdAt": kb.created_at.isoformat() if kb.created_at else None,
"updatedAt": kb.updated_at.isoformat() if kb.updated_at else None,
}
@@ -42,28 +43,35 @@ def doc_to_dict(d: KnowledgeDocument) -> dict:
"kb_id": d.kb_id,
"name": d.name,
"size": d.size,
"file_type": d.file_type,
"storage_url": d.storage_url,
"fileType": d.file_type,
"storageUrl": d.storage_url,
"status": d.status,
"chunk_count": d.chunk_count,
"error_message": d.error_message,
"upload_date": d.upload_date,
"created_at": d.created_at.isoformat() if d.created_at else None,
"processed_at": d.processed_at.isoformat() if d.processed_at else None,
"chunkCount": d.chunk_count,
"errorMessage": d.error_message,
"uploadDate": d.upload_date,
"createdAt": d.created_at.isoformat() if d.created_at else None,
"processedAt": d.processed_at.isoformat() if d.processed_at else None,
}
# ============ Knowledge Bases ============
@router.get("/bases")
def list_knowledge_bases(user_id: int = 1, db: Session = Depends(get_db)):
kbs = db.query(KnowledgeBase).filter(KnowledgeBase.user_id == user_id).all()
def list_knowledge_bases(
user_id: int = 1,
page: int = 1,
limit: int = 50,
db: Session = Depends(get_db)
):
query = db.query(KnowledgeBase).filter(KnowledgeBase.user_id == user_id)
total = query.count()
kbs = query.order_by(KnowledgeBase.created_at.desc()).offset((page - 1) * limit).limit(limit).all()
result = []
for kb in kbs:
docs = db.query(KnowledgeDocument).filter(KnowledgeDocument.kb_id == kb.id).all()
kb_data = kb_to_dict(kb)
kb_data["documents"] = [doc_to_dict(d) for d in docs]
result.append(kb_data)
return {"total": len(result), "list": result}
return {"total": total, "page": page, "limit": limit, "list": result}
@router.get("/bases/{kb_id}")
@@ -91,7 +99,10 @@ def create_knowledge_base(data: KnowledgeBaseCreate, user_id: int = 1, db: Sessi
db.add(kb)
db.commit()
db.refresh(kb)
vector_store.create_collection(kb.id, data.embeddingModel)
try:
vector_store.create_collection(kb.id, data.embeddingModel)
except Exception:
pass
return kb_to_dict(kb)
@@ -101,8 +112,13 @@ def update_knowledge_base(kb_id: str, data: KnowledgeBaseUpdate, db: Session = D
if not kb:
raise HTTPException(status_code=404, detail="Knowledge base not found")
update_data = data.model_dump(exclude_unset=True)
field_map = {
"embeddingModel": "embedding_model",
"chunkSize": "chunk_size",
"chunkOverlap": "chunk_overlap",
}
for field, value in update_data.items():
setattr(kb, field, value)
setattr(kb, field_map.get(field, field), value)
kb.updated_at = datetime.utcnow()
db.commit()
db.refresh(kb)
@@ -114,7 +130,10 @@ def delete_knowledge_base(kb_id: str, db: Session = Depends(get_db)):
kb = db.query(KnowledgeBase).filter(KnowledgeBase.id == kb_id).first()
if not kb:
raise HTTPException(status_code=404, detail="Knowledge base not found")
vector_store.delete_collection(kb_id)
try:
vector_store.delete_collection(kb_id)
except Exception:
pass
docs = db.query(KnowledgeDocument).filter(KnowledgeDocument.kb_id == kb_id).all()
for doc in docs:
db.delete(doc)
@@ -127,10 +146,7 @@ def delete_knowledge_base(kb_id: str, db: Session = Depends(get_db)):
@router.post("/bases/{kb_id}/documents")
def upload_document(
kb_id: str,
name: str = Query(...),
size: str = Query(...),
file_type: str = Query("txt"),
storage_url: Optional[str] = Query(None),
data: KnowledgeDocumentCreate,
db: Session = Depends(get_db)
):
kb = db.query(KnowledgeBase).filter(KnowledgeBase.id == kb_id).first()
@@ -139,17 +155,25 @@ def upload_document(
doc = KnowledgeDocument(
id=str(uuid.uuid4())[:8],
kb_id=kb_id,
name=name,
size=size,
file_type=file_type,
storage_url=storage_url,
name=data.name,
size=data.size,
file_type=data.fileType,
storage_url=data.storageUrl,
status="pending",
upload_date=datetime.utcnow().isoformat()
)
db.add(doc)
db.commit()
db.refresh(doc)
return {"id": doc.id, "name": doc.name, "status": doc.status, "message": "Document created"}
return {
"id": doc.id,
"name": doc.name,
"size": doc.size,
"fileType": doc.file_type,
"storageUrl": doc.storage_url,
"status": doc.status,
"message": "Document created",
}
@router.post("/bases/{kb_id}/documents/{doc_id}/index")
@@ -212,8 +236,9 @@ def delete_document(kb_id: str, doc_id: str, db: Session = Depends(get_db)):
except Exception:
pass
kb = db.query(KnowledgeBase).filter(KnowledgeBase.id == kb_id).first()
kb.chunk_count -= doc.chunk_count
kb.doc_count -= 1
if kb:
kb.chunk_count = max(0, kb.chunk_count - (doc.chunk_count or 0))
kb.doc_count = max(0, kb.doc_count - 1)
db.delete(doc)
db.commit()
return {"message": "Deleted successfully"}