Skip to content

Commit b9b3376

Browse files
committed
feat: support command in mcp
1 parent 2522137 commit b9b3376

File tree

4 files changed

+40
-23
lines changed

4 files changed

+40
-23
lines changed

backend/apps/chat/api/chat.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -198,11 +198,10 @@ async def question_answer_inner(session: SessionDep, current_user: CurrentUser,
198198
if rec_first_chat:
199199
raise Exception(f'Record id: {record_id} does not support this operation')
200200

201-
if command == QuickCommand.REGENERATE:
202-
if rec_analysis_record_id:
203-
raise Exception('Analysis record does not support this operation')
204-
if rec_predict_record_id:
205-
raise Exception('Predict data record does not support this operation')
201+
if rec_analysis_record_id:
202+
raise Exception('Analysis record does not support this operation')
203+
if rec_predict_record_id:
204+
raise Exception('Predict data record does not support this operation')
206205

207206
else: # get last record id
208207
stmt = select(ChatRecord.id, ChatRecord.chat_id, ChatRecord.regenerate_record_id).where(
@@ -233,10 +232,12 @@ async def question_answer_inner(session: SessionDep, current_user: CurrentUser,
233232
finish_step, embedding)
234233

235234
elif command == QuickCommand.ANALYSIS:
236-
return await analysis_or_predict(session, current_user, rec_id, 'analysis', current_assistant, in_chat, stream)
235+
return await analysis_or_predict(session, current_user, rec_id, 'analysis', current_assistant, in_chat,
236+
stream)
237237

238238
elif command == QuickCommand.PREDICT_DATA:
239-
return await analysis_or_predict(session, current_user, rec_id, 'predict', current_assistant, in_chat, stream)
239+
return await analysis_or_predict(session, current_user, rec_id, 'predict', current_assistant, in_chat,
240+
stream)
240241
else:
241242
raise Exception(f'Unknown command: {command.value}')
242243
else:
@@ -247,7 +248,11 @@ async def question_answer_inner(session: SessionDep, current_user: CurrentUser,
247248

248249
if stream:
249250
def _err(_e: Exception):
250-
yield 'data:' + orjson.dumps({'content': str(_e), 'type': 'error'}).decode() + '\n\n'
251+
if in_chat:
252+
yield 'data:' + orjson.dumps({'content': str(_e), 'type': 'error'}).decode() + '\n\n'
253+
else:
254+
yield f'❌ **ERROR:**\n'
255+
yield f'> {str(_e)}\n'
251256

252257
return StreamingResponse(_err(e), media_type="text/event-stream")
253258
else:

backend/apps/chat/curd/chat.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ def get_chat_chart_config(session: SessionDep, chat_record_id: int):
168168
res = session.execute(stmt)
169169
for row in res:
170170
try:
171-
return orjson.loads(row.data)
171+
return orjson.loads(row.chart)
172172
except Exception:
173173
pass
174174
return {}

backend/apps/chat/task/llm.py

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,15 +1172,17 @@ def run_task(self, in_chat: bool = True, stream: bool = True,
11721172
else:
11731173
# generate picture
11741174
try:
1175-
if chart['type'] != 'table':
1175+
if chart.get('type') != 'table':
11761176
yield '### generated chart picture\n\n'
1177-
image_url = request_picture(self.record.chat_id, self.record.id, chart,
1178-
format_json_data(result))
1177+
image_url, error = request_picture(self.record.chat_id, self.record.id, chart,
1178+
format_json_data(result))
11791179
SQLBotLogUtil.info(image_url)
11801180
if stream:
1181-
yield f'![{chart["type"]}]({image_url})'
1181+
yield f'![{chart.get("type")}]({image_url})'
11821182
else:
11831183
json_result['image_url'] = image_url
1184+
if error is not None:
1185+
raise error
11841186
except Exception as e:
11851187
if stream:
11861188
raise e
@@ -1207,7 +1209,8 @@ def run_task(self, in_chat: bool = True, stream: bool = True,
12071209
yield 'data:' + orjson.dumps({'content': error_msg, 'type': 'error'}).decode() + '\n\n'
12081210
else:
12091211
if stream:
1210-
yield f'> ❌ **ERROR**\n\n> \n\n> {error_msg}。'
1212+
yield f'❌ **ERROR:**\n'
1213+
yield f'> {error_msg}\n'
12111214
else:
12121215
json_result['success'] = False
12131216
json_result['message'] = error_msg
@@ -1327,19 +1330,21 @@ def run_analysis_or_predict_task(self, action_type: str, in_chat: bool = True, s
13271330

13281331
# generate picture
13291332
try:
1330-
if chart['type'] != 'table':
1333+
if chart.get('type') != 'table':
13311334
yield '### generated chart picture\n\n'
13321335

13331336
_data = get_chat_chart_data(_session, self.record.id)
1334-
_data['data'] = _data['data'] + predict_data
1337+
_data['data'] = _data.get('data') + predict_data
13351338

1336-
image_url = request_picture(self.record.chat_id, self.record.id, chart,
1337-
format_json_data(_data))
1339+
image_url, error = request_picture(self.record.chat_id, self.record.id, chart,
1340+
format_json_data(_data))
13381341
SQLBotLogUtil.info(image_url)
13391342
if stream:
1340-
yield f'![{chart["type"]}]({image_url})'
1343+
yield f'![{chart.get("type")}]({image_url})'
13411344
else:
13421345
json_result['image_url'] = image_url
1346+
if error is not None:
1347+
raise error
13431348
except Exception as e:
13441349
if stream:
13451350
raise e
@@ -1360,6 +1365,7 @@ def run_analysis_or_predict_task(self, action_type: str, in_chat: bool = True, s
13601365
if not stream:
13611366
yield json_result
13621367
except Exception as e:
1368+
traceback.print_exc()
13631369
error_msg: str
13641370
if isinstance(e, SingleMessageError):
13651371
error_msg = str(e)
@@ -1371,7 +1377,8 @@ def run_analysis_or_predict_task(self, action_type: str, in_chat: bool = True, s
13711377
yield 'data:' + orjson.dumps({'content': error_msg, 'type': 'error'}).decode() + '\n\n'
13721378
else:
13731379
if stream:
1374-
yield f'> ❌ **ERROR**\n\n> \n\n> {error_msg}。'
1380+
yield f'❌ **ERROR:**\n'
1381+
yield f'> {error_msg}\n'
13751382
else:
13761383
json_result['success'] = False
13771384
json_result['message'] = error_msg
@@ -1451,16 +1458,20 @@ def request_picture(chat_id: int, record_id: int, chart: dict, data: dict):
14511458

14521459
request_obj = {
14531460
"path": os.path.join(settings.MCP_IMAGE_PATH, file_name),
1454-
"type": chart['type'],
1461+
"type": chart.get('type'),
14551462
"data": orjson.dumps(data.get('data') if data.get('data') else []).decode(),
14561463
"axis": orjson.dumps(axis).decode(),
14571464
}
14581465

1459-
requests.post(url=settings.MCP_IMAGE_HOST, json=request_obj)
1466+
_error = None
1467+
try:
1468+
requests.post(url=settings.MCP_IMAGE_HOST, json=request_obj, timeout=settings.SERVER_IMAGE_TIMEOUT)
1469+
except Exception as e:
1470+
_error = e
14601471

14611472
request_path = urllib.parse.urljoin(settings.SERVER_IMAGE_HOST, f"{file_name}.png")
14621473

1463-
return request_path
1474+
return request_path, _error
14641475

14651476

14661477
def get_token_usage(chunk: BaseMessageChunk, token_usage: dict = None):

backend/common/core/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ def SQLALCHEMY_DATABASE_URI(self) -> PostgresDsn | str:
8787
EXCEL_PATH: str = '/opt/sqlbot/data/excel'
8888
MCP_IMAGE_HOST: str = 'http://localhost:3000'
8989
SERVER_IMAGE_HOST: str = 'http://YOUR_SERVE_IP:MCP_PORT/images/'
90+
SERVER_IMAGE_TIMEOUT: int = 15
9091

9192
LOCAL_MODEL_PATH: str = '/opt/sqlbot/models'
9293
DEFAULT_EMBEDDING_MODEL: str = 'shibing624/text2vec-base-chinese'

0 commit comments

Comments
 (0)