Skip to content

Commit 6e2ca2c

Browse files
[#78] Refactor patch set-default route into patch update KB & link into MCP server
1 parent 1a038c0 commit 6e2ca2c

File tree

6 files changed

+134
-103
lines changed

6 files changed

+134
-103
lines changed

backend/app/api/api_v1/apps.py

Lines changed: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
KnowledgeBaseItem,
2828
KnowledgeBaseCreateRequest,
2929
KnowledgeBaseResponse,
30+
KnowledgeBaseUpdateRequest,
3031
)
3132
from mcp_clients.kb_mcp_endpoint_service import KnowledgeBaseMCPEndpointService
3233

@@ -189,7 +190,7 @@ def rotate_tokens(
189190
raise HTTPException(
190191
status_code=status.HTTP_400_BAD_REQUEST,
191192
detail=(
192-
"new_callback_token is required when rotate_callback_token is true"
193+
"new_callback_token is required when rotate_callback_token is true" # noqa
193194
),
194195
)
195196
AppService.rotate_callback_token(
@@ -409,7 +410,7 @@ async def create_knowledge_base(
409410

410411

411412
@router.patch(
412-
"/knowledge-bases/{kb_id}/default",
413+
"/knowledge-bases/{kb_id}",
413414
response_model=KnowledgeBaseResponse,
414415
status_code=status.HTTP_200_OK,
415416
responses={
@@ -424,45 +425,34 @@ async def create_knowledge_base(
424425
500: {"model": ErrorResponse, "description": "Internal server error"},
425426
},
426427
)
427-
async def set_default_knowledge_base(
428+
async def update_knowledge_base(
428429
*,
429430
kb_id: int,
430431
db: Session = Depends(get_db),
432+
request_data: KnowledgeBaseUpdateRequest,
431433
current_app: App = Depends(get_current_app),
432434
) -> Any:
433435
"""
434436
Set a specific KB as the default for the authenticated app.
435437
- Automatically unsets the previous default KB.
436438
- Returns the updated KB record.
437439
"""
438-
if current_app.status != "active":
439-
raise HTTPException(
440-
status_code=status.HTTP_403_FORBIDDEN,
441-
detail="App must be active to change default KB.",
442-
)
443-
444440
try:
445-
app_kb = AppService.set_default_knowledge_base(
446-
db=db, app=current_app, kb_id=kb_id
447-
)
448-
449-
# get KB detail from MCP service
450-
kb_mcp_service = KnowledgeBaseMCPEndpointService()
451-
kb_result = await kb_mcp_service.get_kb(kb_id=kb_id)
452-
453-
return KnowledgeBaseResponse(
454-
id=app_kb.id,
455-
knowledge_base_id=app_kb.knowledge_base_id,
456-
name=kb_result.get("name", ""),
457-
description=kb_result.get("description", ""),
458-
is_default=app_kb.is_default,
441+
update_result = await AppService.update_knowledge_base(
442+
db=db,
443+
app=current_app,
444+
kb_id=kb_id,
445+
name=request_data.name,
446+
description=request_data.description,
447+
is_default=request_data.is_default,
459448
)
449+
return update_result
460450
except HTTPException:
461451
raise
462452
except Exception as e:
463453
raise HTTPException(
464454
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
465-
detail=f"Failed to set default KB: {str(e)}",
455+
detail=f"Failed to update KB: {str(e)}",
466456
)
467457

468458

@@ -519,7 +509,7 @@ async def delete_knowledge_base(
519509
if app_kb.is_default:
520510
raise HTTPException(
521511
status_code=status.HTTP_403_FORBIDDEN,
522-
detail="Cannot delete the default knowledge base. Set another KB as default first.",
512+
detail="Cannot delete the default knowledge base. Set another KB as default first.", # noqa
523513
)
524514

525515
try:

backend/app/api/api_v1/jobs.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,15 @@ async def create_job(
4646
],
4747
"callback_params": {"reply_to": "wa:+1234"},
4848
"trace_id": "trace_abc_123",
49-
"knowledge_base_ids": [1, 2] // Optional, defaults to app default KB
49+
"knowledge_base_ids": [1, 2] // Optional, default app KB
5050
}
5151
5252
Example upload job:
5353
{
5454
"job": "upload",
5555
"metadata": {"title": "Chlorination SOP"},
5656
"callback_params": {"ui_upload_id": "up_456"},
57-
"knowledge_base_id": 1 // Optional, defaults to app default KB
57+
"knowledge_base_id": 1 // Optional, default app KB
5858
}
5959
"""
6060
),
@@ -94,6 +94,7 @@ async def create_job(
9494
# 🚀 Handle CHAT jobs
9595
if job_type == "chat":
9696
kb_ids = data.get("knowledge_base_ids", [])
97+
kb_ids = [int(kbid) for kbid in kb_ids]
9798
valid_app_kb_ids = [
9899
kb.knowledge_base_id
99100
for kb in current_app.knowledge_bases
@@ -104,7 +105,7 @@ async def create_job(
104105
if kb_ids and not valid_app_kb_ids:
105106
raise HTTPException(
106107
status_code=404,
107-
detail="Provided knowledge_base_ids are invalid or not linked to this app",
108+
detail="Provided knowledge_base_ids are invalid or not linked to this app", # noqa
108109
)
109110

110111
# If no kb_ids provided, fallback to default KB
@@ -132,6 +133,7 @@ async def create_job(
132133
# 🚀 Handle UPLOAD jobs
133134
elif job_type == "upload":
134135
kb_id = data.get("knowledge_base_id")
136+
kb_id = int(kb_id) if kb_id else None
135137
app_kb = None
136138
if kb_id:
137139
app_kb = next(
@@ -145,7 +147,7 @@ async def create_job(
145147
if not app_kb:
146148
raise HTTPException(
147149
status_code=404,
148-
detail=f"Knowledge base {kb_id} not found or not associated with this app",
150+
detail=f"Knowledge base {kb_id} not found or not associated with this app", # noqa
149151
)
150152

151153
# Default fallback

backend/app/schemas/app.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,16 @@ class KnowledgeBaseCreateRequest(BaseModel):
128128
)
129129

130130

131+
class KnowledgeBaseUpdateRequest(BaseModel):
132+
name: Optional[str] = Field(None, description="Name of the knowledge base")
133+
description: Optional[str] = Field(
134+
None, description="Description of the KB"
135+
)
136+
is_default: Optional[bool] = Field(
137+
None, description="Whether this KB is the default for the app"
138+
)
139+
140+
131141
class KnowledgeBaseResponse(BaseModel):
132142
id: int
133143
knowledge_base_id: int

backend/app/services/app_service.py

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@
44
from fastapi import HTTPException
55

66
from app.models.app import App, AppStatus, AppKnowledgeBase
7-
from app.schemas.app import AppRegisterRequest, AppUpdateRequest
7+
from app.schemas.app import (
8+
AppRegisterRequest,
9+
AppUpdateRequest,
10+
KnowledgeBaseResponse,
11+
)
812
from mcp_clients.kb_mcp_endpoint_service import (
913
KnowledgeBaseMCPEndpointService,
1014
)
@@ -201,11 +205,16 @@ async def create_knowledge_base(
201205
return app_kb
202206

203207
@staticmethod
204-
def set_default_knowledge_base(
205-
db: Session, app: App, kb_id: int
206-
) -> AppKnowledgeBase:
208+
async def update_knowledge_base(
209+
db: Session,
210+
app: App,
211+
kb_id: int,
212+
name: str | None = None,
213+
description: str | None = None,
214+
is_default: bool | None = None,
215+
) -> KnowledgeBaseResponse:
207216
"""
208-
Set the specified KB as the default for the given app.
217+
Update knowledge base detail
209218
"""
210219
app_kb = (
211220
db.query(AppKnowledgeBase)
@@ -217,14 +226,36 @@ def set_default_knowledge_base(
217226
status_code=404, detail="Knowledge base not found for this app"
218227
)
219228

220-
# Unset existing default
221-
AppService._unset_existing_default(db, app)
229+
kb_mcp_service = KnowledgeBaseMCPEndpointService()
230+
231+
data = {}
232+
if name is not None:
233+
data["name"] = name
234+
if description is not None:
235+
data["description"] = description
236+
237+
kb_result = await kb_mcp_service.update_kb(
238+
kb_id=kb_id,
239+
data=data,
240+
)
241+
if not kb_result:
242+
raise HTTPException(
243+
status_code=500, detail="Failed to update KB from MCP service"
244+
)
245+
246+
if is_default is not None:
247+
# Update default
248+
app_kb.is_default = is_default
222249

223-
# Set new default
224-
app_kb.is_default = True
225250
db.commit()
226251
db.refresh(app_kb)
227-
return app_kb
252+
return KnowledgeBaseResponse(
253+
id=app_kb.id,
254+
knowledge_base_id=app_kb.knowledge_base_id,
255+
name=kb_result.get("name"),
256+
description=kb_result.get("description"),
257+
is_default=app_kb.is_default,
258+
)
228259

229260
@staticmethod
230261
def delete_knowledge_base(db: Session, app: App, kb_id: int):

backend/mcp_clients/kb_mcp_endpoint_service.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,14 @@ async def upload_and_process_documents(
192192
filename = os.path.basename(f)
193193
content_type, _ = mimetypes.guess_type(filename)
194194
file_payload.append(
195-
("files", (filename, content, content_type or "application/octet-stream"))
195+
(
196+
"files",
197+
(
198+
filename,
199+
content,
200+
content_type or "application/octet-stream",
201+
),
202+
)
196203
)
197204
else:
198205
raise ValueError(f"Invalid file input: {f!r}")

0 commit comments

Comments
 (0)