feat:为表达添加创建时间
This commit is contained in:
@@ -2,6 +2,7 @@ import time
|
|||||||
import random
|
import random
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
from typing import List, Dict, Optional, Any, Tuple
|
from typing import List, Dict, Optional, Any, Tuple
|
||||||
|
|
||||||
@@ -21,6 +22,16 @@ DECAY_MIN = 0.01 # 最小衰减值
|
|||||||
logger = get_logger("expressor")
|
logger = get_logger("expressor")
|
||||||
|
|
||||||
|
|
||||||
|
def format_create_date(timestamp: float) -> str:
|
||||||
|
"""
|
||||||
|
将时间戳格式化为可读的日期字符串
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
return datetime.fromtimestamp(timestamp).strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
except (ValueError, OSError):
|
||||||
|
return "未知时间"
|
||||||
|
|
||||||
|
|
||||||
def init_prompt() -> None:
|
def init_prompt() -> None:
|
||||||
learn_style_prompt = """
|
learn_style_prompt = """
|
||||||
{chat_str}
|
{chat_str}
|
||||||
@@ -77,6 +88,7 @@ class ExpressionLearner:
|
|||||||
)
|
)
|
||||||
self.llm_model = None
|
self.llm_model = None
|
||||||
self._auto_migrate_json_to_db()
|
self._auto_migrate_json_to_db()
|
||||||
|
self._migrate_old_data_create_date()
|
||||||
|
|
||||||
def _auto_migrate_json_to_db(self):
|
def _auto_migrate_json_to_db(self):
|
||||||
"""
|
"""
|
||||||
@@ -127,6 +139,7 @@ class ExpressionLearner:
|
|||||||
last_active_time=last_active_time,
|
last_active_time=last_active_time,
|
||||||
chat_id=chat_id,
|
chat_id=chat_id,
|
||||||
type=type_str,
|
type=type_str,
|
||||||
|
create_date=last_active_time, # 迁移时使用last_active_time作为创建时间
|
||||||
)
|
)
|
||||||
logger.info(f"已迁移 {expr_file} 到数据库")
|
logger.info(f"已迁移 {expr_file} 到数据库")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -139,6 +152,27 @@ class ExpressionLearner:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"写入done.done标记文件失败: {e}")
|
logger.error(f"写入done.done标记文件失败: {e}")
|
||||||
|
|
||||||
|
def _migrate_old_data_create_date(self):
|
||||||
|
"""
|
||||||
|
为没有create_date的老数据设置创建日期
|
||||||
|
使用last_active_time作为create_date的默认值
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# 查找所有create_date为空的表达方式
|
||||||
|
old_expressions = Expression.select().where(Expression.create_date.is_null())
|
||||||
|
updated_count = 0
|
||||||
|
|
||||||
|
for expr in old_expressions:
|
||||||
|
# 使用last_active_time作为create_date
|
||||||
|
expr.create_date = expr.last_active_time
|
||||||
|
expr.save()
|
||||||
|
updated_count += 1
|
||||||
|
|
||||||
|
if updated_count > 0:
|
||||||
|
logger.info(f"已为 {updated_count} 个老的表达方式设置创建日期")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"迁移老数据创建日期失败: {e}")
|
||||||
|
|
||||||
def get_expression_by_chat_id(self, chat_id: str) -> Tuple[List[Dict[str, float]], List[Dict[str, float]]]:
|
def get_expression_by_chat_id(self, chat_id: str) -> Tuple[List[Dict[str, float]], List[Dict[str, float]]]:
|
||||||
"""
|
"""
|
||||||
获取指定chat_id的style和grammar表达方式
|
获取指定chat_id的style和grammar表达方式
|
||||||
@@ -150,6 +184,8 @@ class ExpressionLearner:
|
|||||||
# 直接从数据库查询
|
# 直接从数据库查询
|
||||||
style_query = Expression.select().where((Expression.chat_id == chat_id) & (Expression.type == "style"))
|
style_query = Expression.select().where((Expression.chat_id == chat_id) & (Expression.type == "style"))
|
||||||
for expr in style_query:
|
for expr in style_query:
|
||||||
|
# 确保create_date存在,如果不存在则使用last_active_time
|
||||||
|
create_date = expr.create_date if expr.create_date is not None else expr.last_active_time
|
||||||
learnt_style_expressions.append(
|
learnt_style_expressions.append(
|
||||||
{
|
{
|
||||||
"situation": expr.situation,
|
"situation": expr.situation,
|
||||||
@@ -158,10 +194,13 @@ class ExpressionLearner:
|
|||||||
"last_active_time": expr.last_active_time,
|
"last_active_time": expr.last_active_time,
|
||||||
"source_id": chat_id,
|
"source_id": chat_id,
|
||||||
"type": "style",
|
"type": "style",
|
||||||
|
"create_date": create_date,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
grammar_query = Expression.select().where((Expression.chat_id == chat_id) & (Expression.type == "grammar"))
|
grammar_query = Expression.select().where((Expression.chat_id == chat_id) & (Expression.type == "grammar"))
|
||||||
for expr in grammar_query:
|
for expr in grammar_query:
|
||||||
|
# 确保create_date存在,如果不存在则使用last_active_time
|
||||||
|
create_date = expr.create_date if expr.create_date is not None else expr.last_active_time
|
||||||
learnt_grammar_expressions.append(
|
learnt_grammar_expressions.append(
|
||||||
{
|
{
|
||||||
"situation": expr.situation,
|
"situation": expr.situation,
|
||||||
@@ -170,10 +209,40 @@ class ExpressionLearner:
|
|||||||
"last_active_time": expr.last_active_time,
|
"last_active_time": expr.last_active_time,
|
||||||
"source_id": chat_id,
|
"source_id": chat_id,
|
||||||
"type": "grammar",
|
"type": "grammar",
|
||||||
|
"create_date": create_date,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return learnt_style_expressions, learnt_grammar_expressions
|
return learnt_style_expressions, learnt_grammar_expressions
|
||||||
|
|
||||||
|
def get_expression_create_info(self, chat_id: str, limit: int = 10) -> List[Dict[str, Any]]:
|
||||||
|
"""
|
||||||
|
获取指定chat_id的表达方式创建信息,按创建日期排序
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
expressions = (Expression.select()
|
||||||
|
.where(Expression.chat_id == chat_id)
|
||||||
|
.order_by(Expression.create_date.desc())
|
||||||
|
.limit(limit))
|
||||||
|
|
||||||
|
result = []
|
||||||
|
for expr in expressions:
|
||||||
|
create_date = expr.create_date if expr.create_date is not None else expr.last_active_time
|
||||||
|
result.append({
|
||||||
|
"situation": expr.situation,
|
||||||
|
"style": expr.style,
|
||||||
|
"type": expr.type,
|
||||||
|
"count": expr.count,
|
||||||
|
"create_date": create_date,
|
||||||
|
"create_date_formatted": format_create_date(create_date),
|
||||||
|
"last_active_time": expr.last_active_time,
|
||||||
|
"last_active_formatted": format_create_date(expr.last_active_time),
|
||||||
|
})
|
||||||
|
|
||||||
|
return result
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"获取表达方式创建信息失败: {e}")
|
||||||
|
return []
|
||||||
|
|
||||||
def is_similar(self, s1: str, s2: str) -> bool:
|
def is_similar(self, s1: str, s2: str) -> bool:
|
||||||
"""
|
"""
|
||||||
判断两个字符串是否相似(只考虑长度大于5且有80%以上重合,不考虑子串)
|
判断两个字符串是否相似(只考虑长度大于5且有80%以上重合,不考虑子串)
|
||||||
@@ -350,6 +419,7 @@ class ExpressionLearner:
|
|||||||
last_active_time=current_time,
|
last_active_time=current_time,
|
||||||
chat_id=chat_id,
|
chat_id=chat_id,
|
||||||
type=type,
|
type=type,
|
||||||
|
create_date=current_time, # 手动设置创建日期
|
||||||
)
|
)
|
||||||
# 限制最大数量
|
# 限制最大数量
|
||||||
exprs = list(
|
exprs = list(
|
||||||
|
|||||||
@@ -132,7 +132,8 @@ class ExpressionSelector:
|
|||||||
"count": expr.count,
|
"count": expr.count,
|
||||||
"last_active_time": expr.last_active_time,
|
"last_active_time": expr.last_active_time,
|
||||||
"source_id": cid,
|
"source_id": cid,
|
||||||
"type": "style"
|
"type": "style",
|
||||||
|
"create_date": expr.create_date if expr.create_date is not None else expr.last_active_time,
|
||||||
} for expr in style_query
|
} for expr in style_query
|
||||||
])
|
])
|
||||||
grammar_exprs.extend([
|
grammar_exprs.extend([
|
||||||
@@ -142,7 +143,8 @@ class ExpressionSelector:
|
|||||||
"count": expr.count,
|
"count": expr.count,
|
||||||
"last_active_time": expr.last_active_time,
|
"last_active_time": expr.last_active_time,
|
||||||
"source_id": cid,
|
"source_id": cid,
|
||||||
"type": "grammar"
|
"type": "grammar",
|
||||||
|
"create_date": expr.create_date if expr.create_date is not None else expr.last_active_time,
|
||||||
} for expr in grammar_query
|
} for expr in grammar_query
|
||||||
])
|
])
|
||||||
style_num = int(total_num * style_percentage)
|
style_num = int(total_num * style_percentage)
|
||||||
|
|||||||
@@ -630,9 +630,7 @@ class StatisticOutputTask(AsyncTask):
|
|||||||
logger.warning(f"获取聊天显示名称失败: {e}")
|
logger.warning(f"获取聊天显示名称失败: {e}")
|
||||||
return chat_id
|
return chat_id
|
||||||
|
|
||||||
def _generate_versions_tab(self, stat: dict) -> str:
|
# 移除_generate_versions_tab方法
|
||||||
"""版本对比功能占位符,防止报错"""
|
|
||||||
return '<div id="versions" class="tab-content"><h2>版本对比</h2><p>暂未实现版本对比功能。</p></div>'
|
|
||||||
|
|
||||||
def _generate_html_report(self, stat: dict[str, Any], now: datetime):
|
def _generate_html_report(self, stat: dict[str, Any], now: datetime):
|
||||||
"""
|
"""
|
||||||
@@ -642,6 +640,7 @@ class StatisticOutputTask(AsyncTask):
|
|||||||
:return: HTML格式的统计报告
|
:return: HTML格式的统计报告
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# 移除版本对比内容相关tab和内容
|
||||||
tab_list = [
|
tab_list = [
|
||||||
f'<button class="tab-link" onclick="showTab(event, \'{period[0]}\')">{period[2]}</button>'
|
f'<button class="tab-link" onclick="showTab(event, \'{period[0]}\')">{period[2]}</button>'
|
||||||
for period in self.stat_period
|
for period in self.stat_period
|
||||||
@@ -771,10 +770,7 @@ class StatisticOutputTask(AsyncTask):
|
|||||||
_format_stat_data(stat["all_time"], "all_time", datetime.fromtimestamp(local_storage["deploy_time"])) # type: ignore
|
_format_stat_data(stat["all_time"], "all_time", datetime.fromtimestamp(local_storage["deploy_time"])) # type: ignore
|
||||||
)
|
)
|
||||||
|
|
||||||
# 添加版本对比内容
|
# 不再添加版本对比内容
|
||||||
versions_tab = self._generate_versions_tab(stat)
|
|
||||||
tab_content_list.append(versions_tab)
|
|
||||||
|
|
||||||
# 添加图表内容
|
# 添加图表内容
|
||||||
chart_data = self._generate_chart_data(stat)
|
chart_data = self._generate_chart_data(stat)
|
||||||
tab_content_list.append(self._generate_chart_tab(chart_data))
|
tab_content_list.append(self._generate_chart_tab(chart_data))
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ from peewee import Model, DoubleField, IntegerField, BooleanField, TextField, Fl
|
|||||||
from .database import db
|
from .database import db
|
||||||
import datetime
|
import datetime
|
||||||
from src.common.logger import get_logger
|
from src.common.logger import get_logger
|
||||||
|
import time
|
||||||
|
|
||||||
logger = get_logger("database_model")
|
logger = get_logger("database_model")
|
||||||
# 请在此处定义您的数据库实例。
|
# 请在此处定义您的数据库实例。
|
||||||
@@ -306,6 +307,7 @@ class Expression(BaseModel):
|
|||||||
last_active_time = FloatField()
|
last_active_time = FloatField()
|
||||||
chat_id = TextField(index=True)
|
chat_id = TextField(index=True)
|
||||||
type = TextField()
|
type = TextField()
|
||||||
|
create_date = FloatField(null=True) # 创建日期,允许为空以兼容老数据
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
table_name = "expression"
|
table_name = "expression"
|
||||||
@@ -449,9 +451,12 @@ def initialize_database():
|
|||||||
alter_sql = f"ALTER TABLE {table_name} ADD COLUMN {field_name} {sql_type}"
|
alter_sql = f"ALTER TABLE {table_name} ADD COLUMN {field_name} {sql_type}"
|
||||||
alter_sql += " NULL" if field_obj.null else " NOT NULL"
|
alter_sql += " NULL" if field_obj.null else " NOT NULL"
|
||||||
if hasattr(field_obj, "default") and field_obj.default is not None:
|
if hasattr(field_obj, "default") and field_obj.default is not None:
|
||||||
# 正确处理不同类型的默认值
|
# 正确处理不同类型的默认值,跳过lambda函数
|
||||||
default_value = field_obj.default
|
default_value = field_obj.default
|
||||||
if isinstance(default_value, str):
|
if callable(default_value):
|
||||||
|
# 跳过lambda函数或其他可调用对象,这些无法在SQL中表示
|
||||||
|
pass
|
||||||
|
elif isinstance(default_value, str):
|
||||||
alter_sql += f" DEFAULT '{default_value}'"
|
alter_sql += f" DEFAULT '{default_value}'"
|
||||||
elif isinstance(default_value, bool):
|
elif isinstance(default_value, bool):
|
||||||
alter_sql += f" DEFAULT {int(default_value)}"
|
alter_sql += f" DEFAULT {int(default_value)}"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
[inner]
|
[inner]
|
||||||
version = "4.4.5"
|
version = "4.4.6"
|
||||||
|
|
||||||
#----以下是给开发人员阅读的,如果你只是部署了麦麦,不需要阅读----
|
#----以下是给开发人员阅读的,如果你只是部署了麦麦,不需要阅读----
|
||||||
#如果你想要修改配置文件,请在修改后将version的值进行变更
|
#如果你想要修改配置文件,请在修改后将version的值进行变更
|
||||||
@@ -151,7 +151,7 @@ mood_decay_rate = 0.95 # 情绪衰减率
|
|||||||
mood_intensity_factor = 1.0 # 情绪强度因子
|
mood_intensity_factor = 1.0 # 情绪强度因子
|
||||||
|
|
||||||
[lpmm_knowledge] # lpmm知识库配置
|
[lpmm_knowledge] # lpmm知识库配置
|
||||||
enable = true # 是否启用lpmm知识库
|
enable = false # 是否启用lpmm知识库
|
||||||
rag_synonym_search_top_k = 10 # 同义词搜索TopK
|
rag_synonym_search_top_k = 10 # 同义词搜索TopK
|
||||||
rag_synonym_threshold = 0.8 # 同义词阈值(相似度高于此阈值的词语会被认为是同义词)
|
rag_synonym_threshold = 0.8 # 同义词阈值(相似度高于此阈值的词语会被认为是同义词)
|
||||||
info_extraction_workers = 3 # 实体提取同时执行线程数,非Pro模型不要设置超过5
|
info_extraction_workers = 3 # 实体提取同时执行线程数,非Pro模型不要设置超过5
|
||||||
|
|||||||
Reference in New Issue
Block a user