Update main.py
Browse files
main.py
CHANGED
@@ -65,38 +65,68 @@ def format_chat_history(messages: List[Message]) -> str:
|
|
65 |
|
66 |
return formatted_history.strip()
|
67 |
|
68 |
-
def
|
69 |
"""
|
70 |
-
|
71 |
-
|
72 |
-
Args:
|
73 |
-
text: Văn bản cần chia
|
74 |
-
words_per_chunk: Số từ trong mỗi chunk
|
75 |
-
delay: Thời gian trễ giữa các chunk (giây)
|
76 |
"""
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
for i in range(0, len(words), words_per_chunk):
|
81 |
-
chunk = ' '.join(words[i:i+words_per_chunk])
|
82 |
-
chunks.append(chunk)
|
83 |
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
91 |
|
92 |
-
|
|
|
|
|
93 |
if await request.is_disconnected():
|
94 |
break
|
95 |
-
|
96 |
-
# Đợi một khoảng thời gian để tạo hiệu ứng streaming
|
97 |
-
await asyncio.sleep(delay)
|
98 |
|
99 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
data = {
|
101 |
"id": response_id,
|
102 |
"object": "chat.completion.chunk",
|
@@ -106,15 +136,30 @@ async def stream_response(content: str, request: Request, response_id: str, mode
|
|
106 |
{
|
107 |
"index": 0,
|
108 |
"delta": {
|
109 |
-
"content":
|
110 |
},
|
111 |
-
"finish_reason": None
|
112 |
}
|
113 |
]
|
114 |
}
|
115 |
-
|
116 |
yield json.dumps(data)
|
117 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
118 |
# Thêm [DONE] để đánh dấu kết thúc stream (theo chuẩn OpenAI)
|
119 |
yield "[DONE]"
|
120 |
|
@@ -151,7 +196,7 @@ async def create_chat_completion(request: Request, response: Response):
|
|
151 |
# Nếu request yêu cầu streaming
|
152 |
if completion_request.stream:
|
153 |
return EventSourceResponse(
|
154 |
-
|
155 |
duck_response,
|
156 |
request,
|
157 |
response_id,
|
|
|
65 |
|
66 |
return formatted_history.strip()
|
67 |
|
68 |
+
async def stream_response_character_by_character(content: str, request: Request, response_id: str, model: str):
|
69 |
"""
|
70 |
+
Generator để stream phản hồi theo từng ký tự với tốc độ phù hợp
|
|
|
|
|
|
|
|
|
|
|
71 |
"""
|
72 |
+
if await request.is_disconnected():
|
73 |
+
return
|
|
|
|
|
|
|
|
|
74 |
|
75 |
+
# Gửi tin nhắn đầu tiên với role và content rỗng
|
76 |
+
data = {
|
77 |
+
"id": response_id,
|
78 |
+
"object": "chat.completion.chunk",
|
79 |
+
"created": int(time.time()),
|
80 |
+
"model": model,
|
81 |
+
"choices": [
|
82 |
+
{
|
83 |
+
"index": 0,
|
84 |
+
"delta": {
|
85 |
+
"role": "assistant",
|
86 |
+
},
|
87 |
+
"finish_reason": None
|
88 |
+
}
|
89 |
+
]
|
90 |
+
}
|
91 |
+
yield json.dumps(data)
|
92 |
+
await asyncio.sleep(0.01) # Đợi một chút trước khi bắt đầu nội dung
|
93 |
|
94 |
+
# Stream nội dung theo từng ký tự
|
95 |
+
buffer = ""
|
96 |
+
for char in content:
|
97 |
if await request.is_disconnected():
|
98 |
break
|
|
|
|
|
|
|
99 |
|
100 |
+
buffer += char
|
101 |
+
|
102 |
+
# Tích lũy ký tự trong buffer và gửi theo các đơn vị có ý nghĩa
|
103 |
+
# (giúp tránh gửi quá nhiều sự kiện nhỏ và đảm bảo hiển thị tốt hơn)
|
104 |
+
if len(buffer) >= 3 or char in [' ', '\n', '.', '!', '?', ',']:
|
105 |
+
data = {
|
106 |
+
"id": response_id,
|
107 |
+
"object": "chat.completion.chunk",
|
108 |
+
"created": int(time.time()),
|
109 |
+
"model": model,
|
110 |
+
"choices": [
|
111 |
+
{
|
112 |
+
"index": 0,
|
113 |
+
"delta": {
|
114 |
+
"content": buffer
|
115 |
+
},
|
116 |
+
"finish_reason": None
|
117 |
+
}
|
118 |
+
]
|
119 |
+
}
|
120 |
+
yield json.dumps(data)
|
121 |
+
buffer = ""
|
122 |
+
|
123 |
+
# Điều chỉnh thời gian delay để có tốc độ stream hợp lý
|
124 |
+
# Ký tự xuống dòng sẽ có thời gian delay lâu hơn một chút
|
125 |
+
delay = 0.05 if char == '\n' else 0.01
|
126 |
+
await asyncio.sleep(delay)
|
127 |
+
|
128 |
+
# Gửi nốt buffer nếu còn
|
129 |
+
if buffer:
|
130 |
data = {
|
131 |
"id": response_id,
|
132 |
"object": "chat.completion.chunk",
|
|
|
136 |
{
|
137 |
"index": 0,
|
138 |
"delta": {
|
139 |
+
"content": buffer
|
140 |
},
|
141 |
+
"finish_reason": None
|
142 |
}
|
143 |
]
|
144 |
}
|
|
|
145 |
yield json.dumps(data)
|
146 |
+
|
147 |
+
# Gửi message cuối cùng để đánh dấu kết thúc
|
148 |
+
data = {
|
149 |
+
"id": response_id,
|
150 |
+
"object": "chat.completion.chunk",
|
151 |
+
"created": int(time.time()),
|
152 |
+
"model": model,
|
153 |
+
"choices": [
|
154 |
+
{
|
155 |
+
"index": 0,
|
156 |
+
"delta": {},
|
157 |
+
"finish_reason": "stop"
|
158 |
+
}
|
159 |
+
]
|
160 |
+
}
|
161 |
+
yield json.dumps(data)
|
162 |
+
|
163 |
# Thêm [DONE] để đánh dấu kết thúc stream (theo chuẩn OpenAI)
|
164 |
yield "[DONE]"
|
165 |
|
|
|
196 |
# Nếu request yêu cầu streaming
|
197 |
if completion_request.stream:
|
198 |
return EventSourceResponse(
|
199 |
+
stream_response_character_by_character(
|
200 |
duck_response,
|
201 |
request,
|
202 |
response_id,
|