Release/v0.2.4 (#397)

* Fix/bug en zh (#389)

* [fix]The log retains genuine alerts and errors, while filtering out unnecessary noise.

* [fix]Scenario English and Chinese, emotion specifications

* [fix]Change the "no data" scenario from 0.0 to None

* [fix]The emotional health indicators, emotional advice, and emotional distribution analysis are all linked together.

* [fix]The emotional health indicators, emotional advice, and emotional distribution analysis are all linked together.

* [fix]Separate expected errors from unexpected errors

* [changes]Translation of emotion labels, and the list of hosts arranged in the order of creation

* [changes]Translation of emotion labels, and the list of hosts arranged in the order of creation

* feat(web): improve knowledge base form validation and parser config handling

- Refactor form validation logic to support tab-specific field validation in edit mode
- Add conditional validation for knowledge graph fields when editing existing knowledge base
- Preserve all existing parser_config fields when merging graphrag configuration
- Skip third-party authentication check when editing on knowledge graph tab
- Update form value retrieval to include disabled fields using getFieldsValue(true)
- Improve comments to clarify parser_config field preservation and validation behavior
- This change enables users to edit knowledge graph settings without re-validating all basic configuration fields

* fix(web): improve infinite scroll handling in knowledge base list

- Add auto-load detection when initial data doesn't fill viewport to prevent empty scrollbar
- Implement scroll height check to automatically load more data if content is insufficient
- Fix hasMore condition to prevent premature loader hiding
- Update loader visibility to only show when data exists and is actively loading
- Refine end message display to show only when all data is loaded and no more items available
- Resolves issue where knowledge base list shows no scrollbar on initial load with limited items

* fix(web): FileUpload bugfix

* fix(web): change skill search key

* Fix/bug en zh (#391)

* [fix]The log retains genuine alerts and errors, while filtering out unnecessary noise.

* [fix]Scenario English and Chinese, emotion specifications

* [fix]Change the "no data" scenario from 0.0 to None

* [fix]The emotional health indicators, emotional advice, and emotional distribution analysis are all linked together.

* [fix]The emotional health indicators, emotional advice, and emotional distribution analysis are all linked together.

* [fix]Separate expected errors from unexpected errors

* [changes]Translation of emotion labels, and the list of hosts arranged in the order of creation

* [changes]Translation of emotion labels, and the list of hosts arranged in the order of creation

* [fix]The mainframe engineering supports Chinese verification.

* [fix]The mainframe engineering supports Chinese verification.

* fix(web): update en

* fix(web): file upload bugfix

* fix(web): memory-write node hide message config

---------

Co-authored-by: 乐力齐 <162269739+lanceyq@users.noreply.github.com>
Co-authored-by: yujiangping <yujiangping@taofen8.com>
Co-authored-by: zhaoying <yzhao96@best-inc.com>
Co-authored-by: yingzhao <zhaoyingyz@126.com>
This commit is contained in:
Ke Sun
2026-02-11 18:19:32 +08:00
committed by GitHub
parent 79b19b744e
commit b272a52b57
15 changed files with 109 additions and 88 deletions

View File

@@ -74,7 +74,7 @@ class OntologyClass(BaseModel):
"""Validate that the class name follows PascalCase convention.
PascalCase rules:
- Must start with an uppercase letter
- Must start with an uppercase letter (for English) or any character (for Chinese/Unicode)
- Cannot contain spaces
- Should not contain special characters except underscores
@@ -90,7 +90,10 @@ class OntologyClass(BaseModel):
if not v:
raise ValueError("Class name cannot be empty")
if not v[0].isupper():
# For Chinese/Unicode characters, skip the uppercase check
# Only check uppercase for ASCII letters
first_char = v[0]
if first_char.isascii() and first_char.isalpha() and not first_char.isupper():
raise ValueError(
f"Class name '{v}' must start with an uppercase letter (PascalCase)"
)
@@ -100,11 +103,11 @@ class OntologyClass(BaseModel):
f"Class name '{v}' cannot contain spaces (PascalCase)"
)
# Check for invalid characters (allow alphanumeric and underscore only)
if not all(c.isalnum() or c == '_' for c in v):
# Check for invalid characters (allow alphanumeric, underscore, and Unicode characters)
if not all(c.isalnum() or c == '_' or ord(c) > 127 for c in v):
raise ValueError(
f"Class name '{v}' contains invalid characters. "
"Only alphanumeric characters and underscores are allowed"
"Only alphanumeric characters, underscores, and Unicode characters are allowed"
)
return v

View File

@@ -88,8 +88,10 @@ class OntologyValidator:
logger.warning(f"Validation failed: {error_msg}")
return False, error_msg
# Check if starts with uppercase letter
if not name[0].isupper():
# Check if starts with uppercase letter (only for ASCII letters)
# For Chinese/Unicode characters, skip this check
first_char = name[0]
if first_char.isascii() and first_char.isalpha() and not first_char.isupper():
error_msg = f"Class name '{name}' must start with an uppercase letter (PascalCase)"
logger.warning(f"Validation failed: {error_msg}")
return False, error_msg
@@ -100,9 +102,9 @@ class OntologyValidator:
logger.warning(f"Validation failed: {error_msg}")
return False, error_msg
# Check for invalid characters (only alphanumeric and underscore allowed)
if not re.match(r'^[A-Za-z0-9_]+$', name):
error_msg = f"Class name '{name}' contains invalid characters. Only alphanumeric characters and underscores are allowed"
# Check for invalid characters (allow alphanumeric, underscore, and Unicode characters)
if not re.match(r'^[A-Za-z0-9_\u4e00-\u9fff]+$', name):
error_msg = f"Class name '{name}' contains invalid characters. Only alphanumeric characters, underscores, and Chinese characters are allowed"
logger.warning(f"Validation failed: {error_msg}")
return False, error_msg

View File

@@ -124,17 +124,17 @@ class EmotionAnalyticsService:
# 将查询结果转换为字典,方便查找
tags_dict = {tag["emotion_type"]: tag for tag in tags}
# 补全缺失的情绪维度,并翻译 emotion_type
# 补全缺失的情绪维度,直接使用英文枚举key前端自行翻译
complete_tags = []
for emotion in all_emotion_types:
if emotion in tags_dict:
tag = tags_dict[emotion].copy()
tag["emotion_type"] = self._translate_emotion_type(emotion, language)
tag["emotion_type"] = emotion
complete_tags.append(tag)
else:
# 如果该情绪类型不存在,添加默认值
complete_tags.append({
"emotion_type": self._translate_emotion_type(emotion, language),
"emotion_type": emotion,
"count": 0,
"percentage": 0.0,
"avg_intensity": 0.0

View File

@@ -55,7 +55,7 @@ def get_workspace_end_users(
) -> List[EndUser]:
"""获取工作空间的所有宿主(优化版本:减少数据库查询次数)
返回结果按 updated_at 从新到旧排序NULL 值排在最后)
返回结果按 created_at 从新到旧排序NULL 值排在最后)
"""
business_logger.info(f"获取工作空间宿主列表: workspace_id={workspace_id}, 操作者: {current_user.username}")
@@ -71,13 +71,13 @@ def get_workspace_end_users(
app_ids = [app.id for app in apps_orm]
# 批量查询所有 end_users一次查询而非循环查询
# 按 updated_at 降序排序NULL 值排在最后id 作为次级排序键保证确定性
# 按 created_at 降序排序NULL 值排在最后id 作为次级排序键保证确定性
from app.models.end_user_model import EndUser as EndUserModel
from sqlalchemy import desc, nullslast
end_users_orm = db.query(EndUserModel).filter(
EndUserModel.app_id.in_(app_ids)
).order_by(
nullslast(desc(EndUserModel.updated_at)),
nullslast(desc(EndUserModel.created_at)),
desc(EndUserModel.id)
).all()