Repository navigation
Expand file tree
/
Copy pathmain.py
More file actions
151 lines (133 loc) · 4.87 KB
/
Copy pathmain.py
File metadata and controls
151 lines (133 loc) · 4.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import os
import tempfile
from uuid import uuid4
from services import S3Client
from botocore.exceptions import ClientError
from fastapi import FastAPI, Depends, Request
from starlette.staticfiles import StaticFiles
from starlette.templating import Jinja2Templates
from schemas import (
KnowledgeUploadSchema, KnowledgeUpdateResponse,
AgentGraphRAGRequest, AgentGraphRAGResponse,
)
from core import AgentGraphRAGBedRock, ChatManager
from server import SocketManager
from workers import aupload_knowledge_base
app = FastAPI(
title="Chat GraphRAG API",
description="API for interacting with a chat system that utilizes a knowledge base.",
version="1.0.0",
)
sio = SocketManager()
sio.mount_to("/socket.io", app)
path__ = os.path.dirname(os.path.abspath(__file__))
app.mount("/public", StaticFiles(directory="%s/public" % path__), name="static")
templates = Jinja2Templates(directory="%s/public/templates" % path__)
@sio.on("chat_history")
async def chat_history(sid, data):
"""
Handle a user joining a chat room.
:param data:
:param sid: The session ID of the user.
"""
chat_id = data.get("chat_id")
if not chat_id:
return await sio.emit("error", {"message": "Chat ID is required to join."}, room=sid)
chat_manager = ChatManager(chat_id)
return await sio.emit(
"history_updated",
{
"history": [
{
"content": h.content,
"role": "user"
if h.type == "human" else "assistant"
}
for h in await chat_manager.get_history()
]
},
room=sid,
)
@sio.on("invoke_agent")
async def invoke_agent(sid, data):
"""
Handle a request to invoke an agent with a chat message.
:param data: The data containing the chat message and any additional information.
:param sid: The session ID of the user.
"""
chat_id = data.get("chat_id")
if not chat_id:
return await sio.emit("error", {"message": "Chat ID is required."}, room=sid)
question = data.get("question")
if not question:
return await sio.emit("error", {"message": "Question is required."}, room=sid)
agent = AgentGraphRAGBedRock(chat_id, sio)
response = await agent.invoke(question)
return await sio.emit(
"agent_response",
{"result": response},
room=sid,
)
@app.get("/")
async def root(request: Request):
"""
Root endpoint that serves the main HTML page.
:return: The rendered HTML template.
"""
return templates.TemplateResponse(request, "index.html", {})
@app.post("/chat/{chat_id}", response_model=AgentGraphRAGResponse)
async def chat(chat_id: str, data: AgentGraphRAGRequest) -> AgentGraphRAGResponse:
"""
Endpoint to handle chat messages.
:param data: The data containing the chat message and any additional information.
:param chat_id: The message to process.
:return: A response containing the processed message.
"""
agent = AgentGraphRAGBedRock(chat_id)
response = await agent.invoke(data.question)
return AgentGraphRAGResponse(**{"result": response})
@app.post("/knowledge/update", response_model=KnowledgeUpdateResponse)
async def update_knowledge(upload: KnowledgeUploadSchema = Depends(KnowledgeUploadSchema)) -> KnowledgeUpdateResponse:
"""
Endpoint to update the knowledge base with a new document.
:param upload: The uploaded files containing the knowledge base document.
:return: A confirmation message.
"""
if len(upload.files) == 0:
return KnowledgeUpdateResponse(
success=False,
message="No files uploaded."
)
job_ids: list[str] = []
s3_client = S3Client()
for file in upload.files:
if not file.filename.endswith(('.pdf', '.txt', '.md')):
return KnowledgeUpdateResponse(
success=False,
message="Unsupported file type. Only PDF, TXT, and MD files are allowed."
)
ext = file.filename.split('.')[-1]
key = f"knowledge/{file.filename}-{str(uuid4())}.{ext}"
try:
temp = tempfile.NamedTemporaryFile(delete=False)
with open(temp.name, 'wb') as f:
f.write(file.file.read())
s3_client.upload_file(temp.name, key)
os.remove(temp.name)
except ClientError as e:
return KnowledgeUpdateResponse(
success=False,
message=f"Failed to upload file to S3: {e}"
)
except FileNotFoundError as e:
return KnowledgeUpdateResponse(
success=False,
message=f"File not found: {e}"
)
job_id = await aupload_knowledge_base(key=key)
job_ids.append(job_id)
return KnowledgeUpdateResponse(
success=True,
message="Knowledge base updated successfully.",
job_ids=job_ids
)