mirror of
https://gh-proxy.org/https://github.com/klinsmaya/SQLBot.git
synced 2026-11-08 01:06:59 +08:00
@@ -54,8 +54,6 @@ from common.utils.utils import SQLBotLogUtil, extract_nested_json, prepare_for_o
|
||||
|
||||
warnings.filterwarnings("ignore")
|
||||
|
||||
base_message_count_limit = 6
|
||||
|
||||
executor = ThreadPoolExecutor(max_workers=200)
|
||||
|
||||
dynamic_ds_types = [1, 3]
|
||||
@@ -95,6 +93,7 @@ class LLMService:
|
||||
articles_number: int = 4
|
||||
|
||||
enable_sql_row_limit: bool = settings.GENERATE_SQL_QUERY_LIMIT_ENABLED
|
||||
base_message_round_count_limit: int = settings.GENERATE_SQL_QUERY_HISTORY_ROUND_COUNT
|
||||
|
||||
def __init__(self, session: Session, current_user: CurrentUser, chat_question: ChatQuestion,
|
||||
current_assistant: Optional[CurrentAssistant] = None, no_reasoning: bool = False,
|
||||
@@ -185,6 +184,14 @@ class LLMService:
|
||||
instance.enable_sql_row_limit = True
|
||||
else:
|
||||
instance.enable_sql_row_limit = False
|
||||
if config.pkey == 'chat.context_record_count':
|
||||
count_value = config.pval
|
||||
if count_value is None:
|
||||
count_value = settings.GENERATE_SQL_QUERY_HISTORY_ROUND_COUNT
|
||||
count_value = int(count_value)
|
||||
if count_value < 0:
|
||||
count_value = 0
|
||||
instance.base_message_round_count_limit = count_value
|
||||
return instance
|
||||
|
||||
def is_running(self, timeout=0.5):
|
||||
@@ -206,22 +213,23 @@ class LLMService:
|
||||
filter(lambda obj: obj.pid == self.chat_question.regenerate_record_id, self.generate_sql_logs), None)
|
||||
last_sql_messages: List[dict[str, Any]] = _temp_log.messages if _temp_log else []
|
||||
|
||||
# todo maybe can configure
|
||||
count_limit = 0 - base_message_count_limit
|
||||
count_limit = self.base_message_round_count_limit
|
||||
|
||||
self.sql_message = []
|
||||
# add sys prompt
|
||||
self.sql_message.append(SystemMessage(
|
||||
content=self.chat_question.sql_sys_question(self.ds.type, self.enable_sql_row_limit)))
|
||||
if last_sql_messages is not None and len(last_sql_messages) > 0:
|
||||
# limit count
|
||||
for last_sql_message in last_sql_messages[count_limit:]:
|
||||
# 获取最后3轮对话
|
||||
last_rounds = get_last_conversation_rounds(last_sql_messages, rounds=count_limit)
|
||||
|
||||
for _msg_dict in last_rounds:
|
||||
_msg: BaseMessage
|
||||
if last_sql_message['type'] == 'human':
|
||||
_msg = HumanMessage(content=last_sql_message['content'])
|
||||
if _msg_dict.get('type') == 'human':
|
||||
_msg = HumanMessage(content=_msg_dict.get('content'))
|
||||
self.sql_message.append(_msg)
|
||||
elif last_sql_message['type'] == 'ai':
|
||||
_msg = AIMessage(content=last_sql_message['content'])
|
||||
elif _msg_dict.get('type') == 'ai':
|
||||
_msg = AIMessage(content=_msg_dict.get('content'))
|
||||
self.sql_message.append(_msg)
|
||||
|
||||
last_chart_messages: List[dict[str, Any]] = self.generate_chart_logs[-1].messages if len(
|
||||
@@ -1666,3 +1674,29 @@ def get_lang_name(lang: str):
|
||||
if normalized.startswith('ko'):
|
||||
return '韩语'
|
||||
return '简体中文'
|
||||
|
||||
|
||||
def get_last_conversation_rounds(messages, rounds=settings.GENERATE_SQL_QUERY_HISTORY_ROUND_COUNT):
|
||||
"""获取最后N轮对话,处理不完整对话的情况"""
|
||||
if not messages or rounds <= 0:
|
||||
return []
|
||||
|
||||
# 找到所有用户消息的位置
|
||||
human_indices = []
|
||||
for index, msg in enumerate(messages):
|
||||
if msg.get('type') == 'human':
|
||||
human_indices.append(index)
|
||||
|
||||
# 如果没有用户消息,返回空
|
||||
if not human_indices:
|
||||
return []
|
||||
|
||||
# 计算从哪个索引开始
|
||||
if len(human_indices) <= rounds:
|
||||
# 如果用户消息数少于等于需要的轮数,从第一个用户消息开始
|
||||
start_index = human_indices[0]
|
||||
else:
|
||||
# 否则,从倒数第N个用户消息开始
|
||||
start_index = human_indices[-rounds]
|
||||
|
||||
return messages[start_index:]
|
||||
|
||||
@@ -109,6 +109,7 @@ class Settings(BaseSettings):
|
||||
|
||||
# 是否启用SQL查询行数限制,默认值,可被参数配置覆盖
|
||||
GENERATE_SQL_QUERY_LIMIT_ENABLED: bool = True
|
||||
GENERATE_SQL_QUERY_HISTORY_ROUND_COUNT: int = 3
|
||||
|
||||
PARSE_REASONING_BLOCK_ENABLED: bool = True
|
||||
DEFAULT_REASONING_CONTENT_START: str = '<think>'
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
"memo": "Memo update rules: Match table name and field name. If a match is found, update the table memo and field memo; otherwise, leave the memo unchanged.",
|
||||
"parameter_configuration": "Parameter Config",
|
||||
"question_count_settings": "Question Count Settings",
|
||||
"context_record_count": "Context Record Count",
|
||||
"context_record_count_hint": "Number of user question rounds",
|
||||
"model_thinking_process": "Expand Model Thinking Process",
|
||||
"rows_of_data": "Limit 1000 Rows of Data",
|
||||
"third_party_platform_settings": "Third-Party Platform Settings",
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
"memo": "메모 업데이트 규칙: 테이블 이름과 필드 이름이 일치하는지 확인합니다. 일치하는 항목이 있으면 테이블 메모와 필드 메모를 업데이트하고, 그렇지 않으면 메모를 변경하지 않고 그대로 둡니다.",
|
||||
"parameter_configuration": "매개변수 구성",
|
||||
"question_count_settings": "질문 수 설정",
|
||||
"context_record_count": "컨텍스트 기록 수",
|
||||
"context_record_count_hint": "사용자 질문 라운드 수",
|
||||
"model_thinking_process": "모델 사고 프로세스 확장",
|
||||
"rows_of_data": "데이터 1,000행 제한",
|
||||
"third_party_platform_settings": "타사 플랫폼 설정",
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
"memo": "备注更新规则:根据表名和字段名匹配,如果匹配则更新表备注和字段备注;如果匹配不上,备注保持不变。",
|
||||
"parameter_configuration": "参数配置",
|
||||
"question_count_settings": "问数设置",
|
||||
"context_record_count": "上下文记录数",
|
||||
"context_record_count_hint": "用户提问轮数",
|
||||
"model_thinking_process": "展开模型思考过程",
|
||||
"rows_of_data": "限制 1000 行数据",
|
||||
"third_party_platform_settings": "第三方平台设置",
|
||||
|
||||
@@ -31,6 +31,13 @@ const loadData = () => {
|
||||
})
|
||||
}
|
||||
|
||||
const onContextRecordCountChange = (count: number) => {
|
||||
if (count < 0) {
|
||||
state.parameterForm['chat.context_record_count'] = 0
|
||||
}
|
||||
state.parameterForm['chat.context_record_count'] = Math.floor(count)
|
||||
}
|
||||
|
||||
const beforeChange = (): Promise<boolean> => {
|
||||
return new Promise((resolve) => {
|
||||
if (!state.parameterForm['chat.rows_of_data']) {
|
||||
@@ -88,41 +95,66 @@ onMounted(() => {
|
||||
<div class="card-title">
|
||||
{{ t('parameter.question_count_settings') }}
|
||||
</div>
|
||||
<div class="card-item">
|
||||
<div class="label">
|
||||
{{ t('parameter.model_thinking_process') }}
|
||||
<el-row>
|
||||
<div class="card-item">
|
||||
<div class="label">
|
||||
{{ t('parameter.model_thinking_process') }}
|
||||
|
||||
<el-tooltip effect="dark" :content="t('parameter.closed_by_default')" placement="top">
|
||||
<el-icon size="16">
|
||||
<icon_info_outlined_1></icon_info_outlined_1>
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
<el-tooltip effect="dark" :content="t('parameter.closed_by_default')" placement="top">
|
||||
<el-icon size="16">
|
||||
<icon_info_outlined_1></icon_info_outlined_1>
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div class="value">
|
||||
<el-switch v-model="state.parameterForm['chat.expand_thinking_block']" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="value">
|
||||
<el-switch v-model="state.parameterForm['chat.expand_thinking_block']" />
|
||||
<div class="card-item" style="margin-left: 16px">
|
||||
<div class="label">
|
||||
{{ t('parameter.rows_of_data') }}
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="t('parameter.excessive_data_volume')"
|
||||
placement="top"
|
||||
>
|
||||
<el-icon size="16">
|
||||
<icon_info_outlined_1></icon_info_outlined_1>
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div class="value">
|
||||
<el-switch
|
||||
v-model="state.parameterForm['chat.limit_rows']"
|
||||
:before-change="beforeChange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-item" style="margin-left: 16px">
|
||||
<div class="label">
|
||||
{{ t('parameter.rows_of_data') }}
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="t('parameter.excessive_data_volume')"
|
||||
placement="top"
|
||||
>
|
||||
<el-icon size="16">
|
||||
<icon_info_outlined_1></icon_info_outlined_1>
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<div class="card-item">
|
||||
<div class="label">
|
||||
{{ t('parameter.context_record_count') }}
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="t('parameter.context_record_count_hint')"
|
||||
placement="top"
|
||||
>
|
||||
<el-icon size="16">
|
||||
<icon_info_outlined_1></icon_info_outlined_1>
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div class="value">
|
||||
<el-input-number
|
||||
v-model.number="state.parameterForm['chat.context_record_count']"
|
||||
min="0"
|
||||
step="1"
|
||||
@change="onContextRecordCountChange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="value">
|
||||
<el-switch
|
||||
v-model="state.parameterForm['chat.limit_rows']"
|
||||
:before-change="beforeChange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
<platform-param />
|
||||
@@ -152,7 +184,6 @@ onMounted(() => {
|
||||
}
|
||||
.title {
|
||||
font-weight: 500;
|
||||
font-style: Medium;
|
||||
font-size: 20px;
|
||||
line-height: 28px;
|
||||
margin-bottom: 16px;
|
||||
@@ -164,12 +195,11 @@ onMounted(() => {
|
||||
padding: 16px;
|
||||
border: 1px solid #dee0e3;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: column;
|
||||
margin-top: 16px;
|
||||
|
||||
.card-title {
|
||||
font-weight: 500;
|
||||
font-style: Medium;
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
width: 100%;
|
||||
|
||||
Reference in New Issue
Block a user