feat: User information in the application conversation log. (#2599)
This commit is contained in:
parent
aab6a2cdf3
commit
1a7f484a62
@ -124,9 +124,11 @@ def event_content(response,
|
|||||||
request_token = 0
|
request_token = 0
|
||||||
response_token = 0
|
response_token = 0
|
||||||
write_context(step, manage, request_token, response_token, all_text)
|
write_context(step, manage, request_token, response_token, all_text)
|
||||||
|
asker = manage.context.get('form_data', {}).get('asker', None)
|
||||||
post_response_handler.handler(chat_id, chat_record_id, paragraph_list, problem_text,
|
post_response_handler.handler(chat_id, chat_record_id, paragraph_list, problem_text,
|
||||||
all_text, manage, step, padding_problem_text, client_id,
|
all_text, manage, step, padding_problem_text, client_id,
|
||||||
reasoning_content=reasoning_content if reasoning_content_enable else '')
|
reasoning_content=reasoning_content if reasoning_content_enable else ''
|
||||||
|
, asker=asker)
|
||||||
yield manage.get_base_to_response().to_stream_chunk_response(chat_id, str(chat_record_id), 'ai-chat-node',
|
yield manage.get_base_to_response().to_stream_chunk_response(chat_id, str(chat_record_id), 'ai-chat-node',
|
||||||
[], '', True,
|
[], '', True,
|
||||||
request_token, response_token,
|
request_token, response_token,
|
||||||
@ -137,8 +139,10 @@ def event_content(response,
|
|||||||
logging.getLogger("max_kb_error").error(f'{str(e)}:{traceback.format_exc()}')
|
logging.getLogger("max_kb_error").error(f'{str(e)}:{traceback.format_exc()}')
|
||||||
all_text = 'Exception:' + str(e)
|
all_text = 'Exception:' + str(e)
|
||||||
write_context(step, manage, 0, 0, all_text)
|
write_context(step, manage, 0, 0, all_text)
|
||||||
|
asker = manage.context.get('asker', None)
|
||||||
post_response_handler.handler(chat_id, chat_record_id, paragraph_list, problem_text,
|
post_response_handler.handler(chat_id, chat_record_id, paragraph_list, problem_text,
|
||||||
all_text, manage, step, padding_problem_text, client_id)
|
all_text, manage, step, padding_problem_text, client_id, reasoning_content='',
|
||||||
|
asker=asker)
|
||||||
add_access_num(client_id, client_type, manage.context.get('application_id'))
|
add_access_num(client_id, client_type, manage.context.get('application_id'))
|
||||||
yield manage.get_base_to_response().to_stream_chunk_response(chat_id, str(chat_record_id), 'ai-chat-node',
|
yield manage.get_base_to_response().to_stream_chunk_response(chat_id, str(chat_record_id), 'ai-chat-node',
|
||||||
[], all_text,
|
[], all_text,
|
||||||
@ -150,7 +154,6 @@ def event_content(response,
|
|||||||
'reasoning_content': ''})
|
'reasoning_content': ''})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class BaseChatStep(IChatStep):
|
class BaseChatStep(IChatStep):
|
||||||
def execute(self, message_list: List[BaseMessage],
|
def execute(self, message_list: List[BaseMessage],
|
||||||
chat_id,
|
chat_id,
|
||||||
@ -304,9 +307,11 @@ class BaseChatStep(IChatStep):
|
|||||||
else:
|
else:
|
||||||
reasoning_content = reasoning_result.get('reasoning_content') + reasoning_result_end.get(
|
reasoning_content = reasoning_result.get('reasoning_content') + reasoning_result_end.get(
|
||||||
'reasoning_content')
|
'reasoning_content')
|
||||||
|
asker = manage.context.get('asker', None)
|
||||||
post_response_handler.handler(chat_id, chat_record_id, paragraph_list, problem_text,
|
post_response_handler.handler(chat_id, chat_record_id, paragraph_list, problem_text,
|
||||||
content, manage, self, padding_problem_text, client_id,
|
content, manage, self, padding_problem_text, client_id,
|
||||||
reasoning_content=reasoning_content if reasoning_content_enable else '')
|
reasoning_content=reasoning_content if reasoning_content_enable else '',
|
||||||
|
asker=asker)
|
||||||
add_access_num(client_id, client_type, manage.context.get('application_id'))
|
add_access_num(client_id, client_type, manage.context.get('application_id'))
|
||||||
return manage.get_base_to_response().to_block_response(str(chat_id), str(chat_record_id),
|
return manage.get_base_to_response().to_block_response(str(chat_id), str(chat_record_id),
|
||||||
content, True,
|
content, True,
|
||||||
@ -320,8 +325,10 @@ class BaseChatStep(IChatStep):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
all_text = 'Exception:' + str(e)
|
all_text = 'Exception:' + str(e)
|
||||||
write_context(self, manage, 0, 0, all_text)
|
write_context(self, manage, 0, 0, all_text)
|
||||||
|
asker = manage.context.get('asker', None)
|
||||||
post_response_handler.handler(chat_id, chat_record_id, paragraph_list, problem_text,
|
post_response_handler.handler(chat_id, chat_record_id, paragraph_list, problem_text,
|
||||||
all_text, manage, self, padding_problem_text, client_id)
|
all_text, manage, self, padding_problem_text, client_id, reasoning_content='',
|
||||||
|
asker=asker)
|
||||||
add_access_num(client_id, client_type, manage.context.get('application_id'))
|
add_access_num(client_id, client_type, manage.context.get('application_id'))
|
||||||
return manage.get_base_to_response().to_block_response(str(chat_id), str(chat_record_id), all_text, True, 0,
|
return manage.get_base_to_response().to_block_response(str(chat_id), str(chat_record_id), all_text, True, 0,
|
||||||
0, _status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
0, _status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||||
|
|||||||
@ -84,7 +84,8 @@ class WorkFlowPostHandler:
|
|||||||
answer_text_list=answer_text_list,
|
answer_text_list=answer_text_list,
|
||||||
run_time=time.time() - workflow.context['start_time'],
|
run_time=time.time() - workflow.context['start_time'],
|
||||||
index=0)
|
index=0)
|
||||||
self.chat_info.append_chat_record(chat_record, self.client_id)
|
asker = workflow.context.get('asker', None)
|
||||||
|
self.chat_info.append_chat_record(chat_record, self.client_id, asker)
|
||||||
# 重新设置缓存
|
# 重新设置缓存
|
||||||
chat_cache.set(chat_id,
|
chat_cache.set(chat_id,
|
||||||
self.chat_info, timeout=60 * 30)
|
self.chat_info, timeout=60 * 30)
|
||||||
|
|||||||
20
apps/application/migrations/0026_chat_asker.py
Normal file
20
apps/application/migrations/0026_chat_asker.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# Generated by Django 4.2.18 on 2025-03-18 06:05
|
||||||
|
|
||||||
|
import application.models.application
|
||||||
|
import common.encoder.encoder
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('application', '0025_alter_application_prologue'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='chat',
|
||||||
|
name='asker',
|
||||||
|
field=models.JSONField(default=application.models.application.default_asker, encoder=common.encoder.encoder.SystemEncoder, verbose_name='访问者'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -115,10 +115,15 @@ class ApplicationDatasetMapping(AppModelMixin):
|
|||||||
db_table = "application_dataset_mapping"
|
db_table = "application_dataset_mapping"
|
||||||
|
|
||||||
|
|
||||||
|
def default_asker():
|
||||||
|
return {'user_name': '游客'}
|
||||||
|
|
||||||
|
|
||||||
class Chat(AppModelMixin):
|
class Chat(AppModelMixin):
|
||||||
id = models.UUIDField(primary_key=True, max_length=128, default=uuid.uuid1, editable=False, verbose_name="主键id")
|
id = models.UUIDField(primary_key=True, max_length=128, default=uuid.uuid1, editable=False, verbose_name="主键id")
|
||||||
application = models.ForeignKey(Application, on_delete=models.CASCADE)
|
application = models.ForeignKey(Application, on_delete=models.CASCADE)
|
||||||
abstract = models.CharField(max_length=1024, verbose_name="摘要")
|
abstract = models.CharField(max_length=1024, verbose_name="摘要")
|
||||||
|
asker = models.JSONField(verbose_name="访问者", default=default_asker, encoder=SystemEncoder)
|
||||||
client_id = models.UUIDField(verbose_name="客户端id", default=None, null=True)
|
client_id = models.UUIDField(verbose_name="客户端id", default=None, null=True)
|
||||||
is_deleted = models.BooleanField(verbose_name="", default=False)
|
is_deleted = models.BooleanField(verbose_name="", default=False)
|
||||||
|
|
||||||
|
|||||||
@ -116,13 +116,15 @@ class ChatInfo:
|
|||||||
}
|
}
|
||||||
|
|
||||||
def to_pipeline_manage_params(self, problem_text: str, post_response_handler: PostResponseHandler,
|
def to_pipeline_manage_params(self, problem_text: str, post_response_handler: PostResponseHandler,
|
||||||
exclude_paragraph_id_list, client_id: str, client_type, stream=True):
|
exclude_paragraph_id_list, client_id: str, client_type, stream=True, form_data=None):
|
||||||
|
if form_data is None:
|
||||||
|
form_data = {}
|
||||||
params = self.to_base_pipeline_manage_params()
|
params = self.to_base_pipeline_manage_params()
|
||||||
return {**params, 'problem_text': problem_text, 'post_response_handler': post_response_handler,
|
return {**params, 'problem_text': problem_text, 'post_response_handler': post_response_handler,
|
||||||
'exclude_paragraph_id_list': exclude_paragraph_id_list, 'stream': stream, 'client_id': client_id,
|
'exclude_paragraph_id_list': exclude_paragraph_id_list, 'stream': stream, 'client_id': client_id,
|
||||||
'client_type': client_type}
|
'client_type': client_type, 'form_data': form_data}
|
||||||
|
|
||||||
def append_chat_record(self, chat_record: ChatRecord, client_id=None):
|
def append_chat_record(self, chat_record: ChatRecord, client_id=None, asker=None):
|
||||||
chat_record.problem_text = chat_record.problem_text[0:10240] if chat_record.problem_text is not None else ""
|
chat_record.problem_text = chat_record.problem_text[0:10240] if chat_record.problem_text is not None else ""
|
||||||
chat_record.answer_text = chat_record.answer_text[0:40960] if chat_record.problem_text is not None else ""
|
chat_record.answer_text = chat_record.answer_text[0:40960] if chat_record.problem_text is not None else ""
|
||||||
is_save = True
|
is_save = True
|
||||||
@ -137,8 +139,17 @@ class ChatInfo:
|
|||||||
if self.application.id is not None:
|
if self.application.id is not None:
|
||||||
# 插入数据库
|
# 插入数据库
|
||||||
if not QuerySet(Chat).filter(id=self.chat_id).exists():
|
if not QuerySet(Chat).filter(id=self.chat_id).exists():
|
||||||
|
asker_dict = {'user_name': '游客'}
|
||||||
|
if asker is not None:
|
||||||
|
if isinstance(asker, str):
|
||||||
|
asker_dict = {
|
||||||
|
'user_name': asker
|
||||||
|
}
|
||||||
|
elif isinstance(asker, dict):
|
||||||
|
asker_dict = asker
|
||||||
|
|
||||||
Chat(id=self.chat_id, application_id=self.application.id, abstract=chat_record.problem_text[0:1024],
|
Chat(id=self.chat_id, application_id=self.application.id, abstract=chat_record.problem_text[0:1024],
|
||||||
client_id=client_id, update_time=datetime.now()).save()
|
client_id=client_id, asker=asker_dict, update_time=datetime.now()).save()
|
||||||
else:
|
else:
|
||||||
Chat.objects.filter(id=self.chat_id).update(update_time=datetime.now())
|
Chat.objects.filter(id=self.chat_id).update(update_time=datetime.now())
|
||||||
# 插入会话记录
|
# 插入会话记录
|
||||||
@ -171,7 +182,8 @@ def get_post_handler(chat_info: ChatInfo):
|
|||||||
answer_text_list=answer_list,
|
answer_text_list=answer_list,
|
||||||
run_time=manage.context['run_time'],
|
run_time=manage.context['run_time'],
|
||||||
index=len(chat_info.chat_record_list) + 1)
|
index=len(chat_info.chat_record_list) + 1)
|
||||||
chat_info.append_chat_record(chat_record, client_id)
|
asker = kwargs.get("asker", None)
|
||||||
|
chat_info.append_chat_record(chat_record, client_id, asker=asker)
|
||||||
# 重新设置缓存
|
# 重新设置缓存
|
||||||
chat_cache.set(chat_id,
|
chat_cache.set(chat_id,
|
||||||
chat_info, timeout=60 * 30)
|
chat_info, timeout=60 * 30)
|
||||||
@ -310,6 +322,7 @@ class ChatMessageSerializer(serializers.Serializer):
|
|||||||
stream = self.data.get('stream')
|
stream = self.data.get('stream')
|
||||||
client_id = self.data.get('client_id')
|
client_id = self.data.get('client_id')
|
||||||
client_type = self.data.get('client_type')
|
client_type = self.data.get('client_type')
|
||||||
|
form_data = self.data.get("form_data")
|
||||||
pipeline_manage_builder = PipelineManage.builder()
|
pipeline_manage_builder = PipelineManage.builder()
|
||||||
# 如果开启了问题优化,则添加上问题优化步骤
|
# 如果开启了问题优化,则添加上问题优化步骤
|
||||||
if chat_info.application.problem_optimization:
|
if chat_info.application.problem_optimization:
|
||||||
@ -331,7 +344,7 @@ class ChatMessageSerializer(serializers.Serializer):
|
|||||||
exclude_paragraph_id_list = list(set(paragraph_id_list))
|
exclude_paragraph_id_list = list(set(paragraph_id_list))
|
||||||
# 构建运行参数
|
# 构建运行参数
|
||||||
params = chat_info.to_pipeline_manage_params(message, get_post_handler(chat_info), exclude_paragraph_id_list,
|
params = chat_info.to_pipeline_manage_params(message, get_post_handler(chat_info), exclude_paragraph_id_list,
|
||||||
client_id, client_type, stream)
|
client_id, client_type, stream, form_data)
|
||||||
# 运行流水线作业
|
# 运行流水线作业
|
||||||
pipeline_message.run(params)
|
pipeline_message.run(params)
|
||||||
return pipeline_message.context['chat_result']
|
return pipeline_message.context['chat_result']
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
SELECT
|
SELECT
|
||||||
*
|
*,to_json(asker) as asker
|
||||||
FROM
|
FROM
|
||||||
application_chat application_chat
|
application_chat application_chat
|
||||||
LEFT JOIN (
|
LEFT JOIN (
|
||||||
|
|||||||
@ -276,6 +276,25 @@ function handleInputFieldList() {
|
|||||||
: { title: t('chat.userInput') }
|
: { title: t('chat.userInput') }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
const getRouteQueryValue = (field: string) => {
|
||||||
|
let _value = route.query[field]
|
||||||
|
if (_value != null) {
|
||||||
|
if (_value instanceof Array) {
|
||||||
|
_value = _value
|
||||||
|
.map((item) => {
|
||||||
|
if (item != null) {
|
||||||
|
return decodeQuery(item)
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
})
|
||||||
|
.filter((item) => item != null)
|
||||||
|
} else {
|
||||||
|
_value = decodeQuery(_value)
|
||||||
|
}
|
||||||
|
return _value
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 校验参数
|
* 校验参数
|
||||||
*/
|
*/
|
||||||
@ -294,20 +313,8 @@ const checkInputParam = () => {
|
|||||||
let msg = []
|
let msg = []
|
||||||
for (let f of apiInputFieldList.value) {
|
for (let f of apiInputFieldList.value) {
|
||||||
if (!api_form_data_context.value[f.field]) {
|
if (!api_form_data_context.value[f.field]) {
|
||||||
let _value = route.query[f.field]
|
let _value = getRouteQueryValue(f.field)
|
||||||
if (_value != null) {
|
if (_value != null) {
|
||||||
if (_value instanceof Array) {
|
|
||||||
_value = _value
|
|
||||||
.map((item) => {
|
|
||||||
if (item != null) {
|
|
||||||
return decodeQuery(item)
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
})
|
|
||||||
.filter((item) => item != null)
|
|
||||||
} else {
|
|
||||||
_value = decodeQuery(_value)
|
|
||||||
}
|
|
||||||
api_form_data_context.value[f.field] = _value
|
api_form_data_context.value[f.field] = _value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -315,6 +322,10 @@ const checkInputParam = () => {
|
|||||||
msg.push(f.field)
|
msg.push(f.field)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!api_form_data_context.value['asker']) {
|
||||||
|
api_form_data_context.value['asker'] = getRouteQueryValue('asker')
|
||||||
|
}
|
||||||
|
|
||||||
if (msg.length > 0) {
|
if (msg.length > 0) {
|
||||||
MsgWarning(
|
MsgWarning(
|
||||||
`${t('chat.tip.inputParamMessage1')} ${msg.join('、')}${t('chat.tip.inputParamMessage2')}`
|
`${t('chat.tip.inputParamMessage1')} ${msg.join('、')}${t('chat.tip.inputParamMessage2')}`
|
||||||
|
|||||||
@ -13,6 +13,7 @@ export default {
|
|||||||
table: {
|
table: {
|
||||||
abstract: 'Title',
|
abstract: 'Title',
|
||||||
chat_record_count: 'Total Messages',
|
chat_record_count: 'Total Messages',
|
||||||
|
user: 'User',
|
||||||
feedback: {
|
feedback: {
|
||||||
label: 'User Feedback',
|
label: 'User Feedback',
|
||||||
star: 'Agree',
|
star: 'Agree',
|
||||||
|
|||||||
@ -13,6 +13,7 @@ export default {
|
|||||||
table: {
|
table: {
|
||||||
abstract: '摘要',
|
abstract: '摘要',
|
||||||
chat_record_count: '对话提问数',
|
chat_record_count: '对话提问数',
|
||||||
|
user: '用户',
|
||||||
feedback: {
|
feedback: {
|
||||||
label: '用户反馈',
|
label: '用户反馈',
|
||||||
star: '赞同',
|
star: '赞同',
|
||||||
@ -35,6 +36,6 @@ export default {
|
|||||||
},
|
},
|
||||||
title: {
|
title: {
|
||||||
placeholder: '请给当前内容设置一个标题,以便管理查看'
|
placeholder: '请给当前内容设置一个标题,以便管理查看'
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,6 +13,7 @@ export default {
|
|||||||
table: {
|
table: {
|
||||||
abstract: '摘要',
|
abstract: '摘要',
|
||||||
chat_record_count: '對話提問數',
|
chat_record_count: '對話提問數',
|
||||||
|
user: '用戶',
|
||||||
feedback: {
|
feedback: {
|
||||||
label: '用戶反饋',
|
label: '用戶反饋',
|
||||||
star: '贊同',
|
star: '贊同',
|
||||||
@ -35,6 +36,6 @@ export default {
|
|||||||
},
|
},
|
||||||
title: {
|
title: {
|
||||||
placeholder: '請給當前內容設定一個標題,以便管理查看'
|
placeholder: '請給當前內容設定一個標題,以便管理查看'
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -142,21 +142,16 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="mark_sum" :label="$t('views.log.table.mark')" align="right" />
|
<el-table-column prop="mark_sum" :label="$t('views.log.table.mark')" align="right" />
|
||||||
|
<el-table-column prop="asker" :label="$t('views.log.table.user')">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ row.asker?.user_name }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column :label="$t('views.log.table.recenTimes')" width="180">
|
<el-table-column :label="$t('views.log.table.recenTimes')" width="180">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
{{ datetimeFormat(row.update_time) }}
|
{{ datetimeFormat(row.update_time) }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<!-- <el-table-column label="操作" width="70" align="left">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<el-tooltip effect="dark" :content="$t('common.delete')" placement="top">
|
|
||||||
<el-button type="primary" text @click.stop="deleteLog(row)">
|
|
||||||
<el-icon><Delete /></el-icon>
|
|
||||||
</el-button>
|
|
||||||
</el-tooltip>
|
|
||||||
</template>
|
|
||||||
</el-table-column> -->
|
|
||||||
</app-table>
|
</app-table>
|
||||||
</div>
|
</div>
|
||||||
<ChatRecordDrawer
|
<ChatRecordDrawer
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user