diff --git a/backend/apps/chat/models/chat_model.py b/backend/apps/chat/models/chat_model.py index c1f431d7..c909d6a4 100644 --- a/backend/apps/chat/models/chat_model.py +++ b/backend/apps/chat/models/chat_model.py @@ -111,7 +111,8 @@ class AiModelQuestion(BaseModel): sub_query: Optional[list[dict]] = None def sql_sys_question(self): - return get_sql_template()['system'].format(engine=self.engine, schema=self.db_schema, question=self.question, lang=self.lang) + return get_sql_template()['system'].format(engine=self.engine, schema=self.db_schema, question=self.question, + lang=self.lang) def sql_user_question(self): return get_sql_template()['user'].format(engine=self.engine, schema=self.db_schema, question=self.question, @@ -153,22 +154,29 @@ class AiModelQuestion(BaseModel): def filter_user_question(self): return get_permissions_template()['user'].format(sql=self.sql, filter=self.filter) - - def dynamic_sys_question(self): + + def dynamic_sys_question(self): return get_dynamic_template()['system'].format(lang=self.lang, engine=self.engine) - - def dynamic_user_question(self): + + def dynamic_user_question(self): return get_dynamic_template()['user'].format(sql=self.sql, sub_query=self.sub_query) + class ChatQuestion(AiModelQuestion): - question: str = Body(description='用户提问') - chat_id: int = Body(description='会话ID') + question: str + chat_id: int class ChatMcp(ChatQuestion): - token: str = Body(description='token') + token: str class ChatStart(BaseModel): username: str = Body(description='用户名') password: str = Body(description='密码') + + +class McpQuestion(BaseModel): + question: str = Body(description='用户提问') + chat_id: int = Body(description='会话ID') + token: str = Body(description='token') diff --git a/backend/apps/chat/task/llm.py b/backend/apps/chat/task/llm.py index b208f4e2..f5d8c68d 100644 --- a/backend/apps/chat/task/llm.py +++ b/backend/apps/chat/task/llm.py @@ -1032,7 +1032,7 @@ class LLMService: def validate_history_ds(self): _ds = self.ds if not self.current_assistant: - current_ds = self.session.exec(CoreDatasource, _ds.id) + current_ds = self.session.get(CoreDatasource, _ds.id) if not current_ds: raise Exception('ds is invalid') else: diff --git a/backend/apps/mcp/mcp.py b/backend/apps/mcp/mcp.py index 70373038..19afffe7 100644 --- a/backend/apps/mcp/mcp.py +++ b/backend/apps/mcp/mcp.py @@ -12,7 +12,7 @@ from pydantic import ValidationError from sqlmodel import select from apps.chat.api.chat import create_chat -from apps.chat.models.chat_model import ChatMcp, CreateChat, ChatStart +from apps.chat.models.chat_model import ChatMcp, CreateChat, ChatStart, McpQuestion from apps.chat.task.llm import LLMService from apps.system.crud.user import authenticate from apps.system.crud.user import get_db_user @@ -76,7 +76,7 @@ async def mcp_start(session: SessionDep, chat: ChatStart): @router.post("/mcp_question", operation_id="mcp_question") -async def mcp_question(session: SessionDep, chat: ChatMcp): +async def mcp_question(session: SessionDep, chat: McpQuestion): try: payload = jwt.decode( chat.token, settings.SECRET_KEY, algorithms=[security.ALGORITHM] @@ -105,8 +105,9 @@ async def mcp_question(session: SessionDep, chat: ChatMcp): if session_user.status != 1: raise HTTPException(status_code=400, detail="Inactive user") + mcp_chat = ChatMcp(token=chat.token, chat_id=chat.chat_id, question=chat.question) # ask - llm_service = LLMService(session_user, chat) + llm_service = LLMService(session_user, mcp_chat) llm_service.init_record() return StreamingResponse(llm_service.run_task(False), media_type="text/event-stream") diff --git a/frontend/src/views/chat/component/charts/Bar.ts b/frontend/src/views/chat/component/charts/Bar.ts index d78c8e38..95fb1504 100644 --- a/frontend/src/views/chat/component/charts/Bar.ts +++ b/frontend/src/views/chat/component/charts/Bar.ts @@ -104,28 +104,28 @@ export class Bar extends BaseG2Chart { return { name: y[0].name, value: `${data[y[0].value]}${_data.isPercent ? '%' : ''}` } } }, - labels: [ - { - text: (data: any) => { - const value = data[y[0].value] - if (value === undefined || value === null) { - return '' - } - return `${value}${_data.isPercent ? '%' : ''}` - }, - position: (data: any) => { - if (data[y[0].value] < 0) { - return 'left' - } - return 'right' - }, - transform: [ - { type: 'contrastReverse' }, - { type: 'exceedAdjust' }, - { type: 'overlapHide' }, - ], - }, - ], + // labels: [ + // { + // text: (data: any) => { + // const value = data[y[0].value] + // if (value === undefined || value === null) { + // return '' + // } + // return `${value}${_data.isPercent ? '%' : ''}` + // }, + // position: (data: any) => { + // if (data[y[0].value] < 0) { + // return 'left' + // } + // return 'right' + // }, + // transform: [ + // { type: 'contrastReverse' }, + // { type: 'exceedAdjust' }, + // { type: 'overlapHide' }, + // ], + // }, + // ], } as G2Spec if (series.length > 0) { diff --git a/frontend/src/views/chat/component/charts/Column.ts b/frontend/src/views/chat/component/charts/Column.ts index 0159f81d..ce57113a 100644 --- a/frontend/src/views/chat/component/charts/Column.ts +++ b/frontend/src/views/chat/component/charts/Column.ts @@ -93,28 +93,28 @@ export class Column extends BaseG2Chart { return { name: y[0].name, value: `${data[y[0].value]}${_data.isPercent ? '%' : ''}` } } }, - labels: [ - { - text: (data: any) => { - const value = data[y[0].value] - if (value === undefined || value === null) { - return '' - } - return `${value}${_data.isPercent ? '%' : ''}` - }, - position: (data: any) => { - if (data[y[0].value] < 0) { - return 'bottom' - } - return 'top' - }, - transform: [ - { type: 'contrastReverse' }, - { type: 'exceedAdjust' }, - { type: 'overlapHide' }, - ], - }, - ], + // labels: [ + // { + // text: (data: any) => { + // const value = data[y[0].value] + // if (value === undefined || value === null) { + // return '' + // } + // return `${value}${_data.isPercent ? '%' : ''}` + // }, + // position: (data: any) => { + // if (data[y[0].value] < 0) { + // return 'bottom' + // } + // return 'top' + // }, + // transform: [ + // { type: 'contrastReverse' }, + // { type: 'exceedAdjust' }, + // { type: 'overlapHide' }, + // ], + // }, + // ], } as G2Spec if (series.length > 0) { diff --git a/frontend/src/views/chat/component/charts/Line.ts b/frontend/src/views/chat/component/charts/Line.ts index 43ed6c0a..05fbfca8 100644 --- a/frontend/src/views/chat/component/charts/Line.ts +++ b/frontend/src/views/chat/component/charts/Line.ts @@ -59,26 +59,26 @@ export class Line extends BaseG2Chart { encode: { shape: 'smooth', }, - labels: [ - { - text: (data: any) => { - const value = data[y[0].value] - if (value === undefined || value === null) { - return '' - } - return `${value}${_data.isPercent ? '%' : ''}` - }, - style: { - dx: -10, - dy: -12, - }, - transform: [ - { type: 'contrastReverse' }, - { type: 'exceedAdjust' }, - { type: 'overlapHide' }, - ], - }, - ], + // labels: [ + // { + // text: (data: any) => { + // const value = data[y[0].value] + // if (value === undefined || value === null) { + // return '' + // } + // return `${value}${_data.isPercent ? '%' : ''}` + // }, + // style: { + // dx: -10, + // dy: -12, + // }, + // transform: [ + // { type: 'contrastReverse' }, + // { type: 'exceedAdjust' }, + // { type: 'overlapHide' }, + // ], + // }, + // ], tooltip: (data) => { if (series.length > 0) { return { @@ -95,6 +95,9 @@ export class Line extends BaseG2Chart { style: { fill: 'white', }, + encode: { + size: 1.5, + }, tooltip: false, }, ], diff --git a/frontend/src/views/dashboard/canvas/CanvasCore.vue b/frontend/src/views/dashboard/canvas/CanvasCore.vue index afef79c5..7961a760 100644 --- a/frontend/src/views/dashboard/canvas/CanvasCore.vue +++ b/frontend/src/views/dashboard/canvas/CanvasCore.vue @@ -1232,7 +1232,7 @@ defineExpose({ { right: 12px; top: 12px; display: flex; - z-index: 1; + z-index: 11; cursor: pointer !important; } diff --git a/frontend/src/views/dashboard/components/sq-tab/index.vue b/frontend/src/views/dashboard/components/sq-tab/index.vue index 6085c3be..7b2c0cf9 100644 --- a/frontend/src/views/dashboard/components/sq-tab/index.vue +++ b/frontend/src/views/dashboard/components/sq-tab/index.vue @@ -237,6 +237,7 @@ defineExpose({ :component-data="tabItem.componentData" :canvas-view-info="canvasViewInfo" :base-matrix-count="tabBaseMatrixCount" + :canvas-id="tabItem.name" > { + const recordData = record.data if (record?.predict_record_id !== undefined && record?.predict_record_id !== null) { let _list = [] if (record?.predict_data && typeof record?.predict_data === 'string') { @@ -121,13 +122,15 @@ const getData = (record: any) => { return _list } - if (record.data && record.data.length > 0) { - return concat(record.data, _list) + if (recordData.data && recordData.data.length > 0) { + recordData.data = concat(recordData.data, _list) + } else { + recordData.data = _list } - return _list + return recordData } else { - return record.data + return recordData } } @@ -142,7 +145,7 @@ function adaptorChartInfoList(chatInfo: ChatInfo) { (record?.sql || record?.chart)) || (record?.predict_record_id !== undefined && record?.predict_record_id !== null && - data.length > 0) + data.data.length > 0) ) { const recordeInfo = { id: chatInfo.id + '_' + record.id, data: data, chart: {} } const chartBaseInfo = JSON.parse(record.chart) diff --git a/g2-ssr/charts/line.js b/g2-ssr/charts/line.js index 72931edf..23be4550 100644 --- a/g2-ssr/charts/line.js +++ b/g2-ssr/charts/line.js @@ -86,6 +86,9 @@ function getLineOptions(baseOptions, axis, data) { style: { fill: 'white', }, + encode: { + size: 1.5, + }, tooltip: false, }, ], diff --git a/start.sh b/start.sh index eb018a76..bc4fd998 100644 --- a/start.sh +++ b/start.sh @@ -2,5 +2,7 @@ SSR_PATH=/opt/sqlbot/g2-ssr APP_PATH=/opt/sqlbot/app nohup node $SSR_PATH/app.js & +nohup uvicorn main:mcp_app --host 0.0.0.0 --port 8001 & + cd $APP_PATH uvicorn main:app --host 0.0.0.0 --port 8000 --workers 1 --proxy-headers