fix: enhance manage_personalization tool display

This commit is contained in:
JOJO 2026-04-14 13:44:06 +08:00
parent 916f68e8e9
commit 1500a15be1
3 changed files with 216 additions and 0 deletions

View File

@ -1424,6 +1424,7 @@ class MainTerminalToolsExecutionMixin:
"success": True,
"message": f"字段 '{field}' 更新成功",
"updated_field": field,
"old_value": old_value,
"updated_value": value
}

View File

@ -163,6 +163,11 @@ function renderEnhancedToolResult(): string {
return renderUpdateMemory(result, args);
}
//
else if (name === 'manage_personalization') {
return renderManagePersonalization(result, args);
}
//
else if (name === 'todo_create') {
return renderTodoCreate(result, args);
@ -702,6 +707,116 @@ function renderUpdateMemory(result: any, args: any): string {
return html;
}
function formatPersonalizationFieldLabel(field: string): string {
const labelMap: Record<string, string> = {
enabled: '个性化功能',
self_identify: 'AI 自称',
user_name: '用户称呼',
profession: '用户职业',
tone: '交流语气',
considerations: '注意事项',
theme: '主题配色',
communication_style: '交流风格'
};
return labelMap[field] || field;
}
function formatPersonalizationFieldValue(field: string, value: any): string {
if (value === null || value === undefined || value === '') {
return '未设置';
}
if (field === 'enabled') {
return value ? '开启' : '关闭';
}
if (field === 'theme') {
const themeMap: Record<string, string> = {
classic: 'classic经典',
light: 'light明亮',
dark: 'dark暗黑'
};
return themeMap[String(value)] || String(value);
}
if (field === 'communication_style') {
const styleMap: Record<string, string> = {
default: 'default标准 AI 风格)',
human_like: 'human_like拟人聊天风格'
};
return styleMap[String(value)] || String(value);
}
if (field === 'considerations') {
if (!Array.isArray(value) || value.length === 0) {
return '未设置';
}
return value.map((item) => String(item)).join('、');
}
return String(value);
}
function renderManagePersonalization(result: any, args: any): string {
const action = String(args.action || result.action || 'read');
const status = formatToolStatusLabel(
result,
action === 'update' ? '✓ 已更新' : '✓ 已读取'
);
let html = '<div class="tool-result-meta">';
html += `<div><strong>操作:</strong>${escapeHtml(action === 'update' ? '更新配置' : '读取配置')}</div>`;
html += `<div><strong>状态:</strong>${status}</div>`;
if (!result?.success) {
if (result?.error) {
html += `<div><strong>错误:</strong>${escapeHtml(String(result.error))}</div>`;
}
if (Array.isArray(result?.validation_errors) && result.validation_errors.length > 0) {
html += `<div><strong>校验:</strong>${escapeHtml(result.validation_errors.join(''))}</div>`;
}
html += '</div>';
return html;
}
if (action === 'update') {
const field = String(result.updated_field || args.field || '');
const oldValue = result.old_value ?? args.old_value;
const newValue = result.updated_value ?? args.value;
if (field) {
html += `<div><strong>字段:</strong>${escapeHtml(formatPersonalizationFieldLabel(field))}</div>`;
html += `<div><strong>新值:</strong>${escapeHtml(formatPersonalizationFieldValue(field, newValue))}</div>`;
if (oldValue !== undefined) {
html += `<div><strong>旧值:</strong>${escapeHtml(formatPersonalizationFieldValue(field, oldValue))}</div>`;
}
}
if (result?.theme_changed && result?.new_theme) {
html += `<div><strong>主题刷新:</strong>${escapeHtml(formatPersonalizationFieldValue('theme', result.new_theme))}</div>`;
}
html += '</div>';
return html;
}
const data = result?.data && typeof result.data === 'object' ? result.data : {};
const entries = Object.entries(data);
html += `<div><strong>配置项:</strong>${entries.length} 项</div>`;
html += '</div>';
if (entries.length > 0) {
html += '<div class="tool-result-content">';
html += '<div class="personalization-config-title">当前个性化配置</div>';
html += '<div class="personalization-config-list">';
entries.forEach(([field, value]) => {
html += '<div class="config-item">';
html += `<span class="config-label">${escapeHtml(formatPersonalizationFieldLabel(field))}</span>`;
html += `<span class="config-value">${escapeHtml(formatPersonalizationFieldValue(field, value))}</span>`;
html += '</div>';
});
html += '</div></div>';
}
return html;
}
// ===== =====
function renderTodoCreate(result: any, args: any): string {
const status = formatToolStatusLabel(result, '✓ 已创建');
@ -1102,4 +1217,65 @@ function renderEasterEgg(result: any, args: any): string {
font-size: 12px;
line-height: 1.5;
}
/* 个性化管理 */
.personalization-message {
padding: 12px;
background: rgba(0, 0, 0, 0.02);
border-radius: 6px;
font-size: 13px;
line-height: 1.6;
white-space: pre-wrap;
}
:root[data-theme='dark'] .personalization-message {
background: rgba(255, 255, 255, 0.05);
}
.personalization-config-title {
font-weight: 600;
margin-bottom: 8px;
color: rgba(0, 0, 0, 0.8);
}
:root[data-theme='dark'] .personalization-config-title {
color: rgba(255, 255, 255, 0.9);
}
.personalization-config-list {
display: grid;
gap: 6px;
}
.config-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 6px 10px;
background: rgba(0, 0, 0, 0.02);
border-radius: 4px;
font-size: 12px;
}
:root[data-theme='dark'] .config-item {
background: rgba(255, 255, 255, 0.05);
}
.config-label {
color: rgba(0, 0, 0, 0.6);
font-weight: 500;
}
:root[data-theme='dark'] .config-label {
color: rgba(255, 255, 255, 0.6);
}
.config-value {
color: rgba(0, 0, 0, 0.9);
font-weight: 400;
}
:root[data-theme='dark'] .config-value {
color: rgba(255, 255, 255, 0.9);
}
</style>

View File

@ -800,6 +800,44 @@ def _format_command_result(label: str, result_data: Dict[str, Any]) -> str:
return "\n".join(lines)
def _format_manage_personalization(result_data: Dict[str, Any]) -> str:
action = result_data.get("action") or "read"
if not result_data.get("success"):
validation_errors = result_data.get("validation_errors") or []
base = _format_failure("manage_personalization", result_data)
if validation_errors:
return base + "\n校验失败: " + "".join(str(item) for item in validation_errors)
return base
if action == "update" or result_data.get("updated_field"):
field = result_data.get("updated_field") or "未知字段"
old_value = result_data.get("old_value")
new_value = result_data.get("updated_value")
parts = [f"个性化字段已更新: {field}"]
if old_value is not None:
parts.append(f"旧值: {old_value}")
if new_value is not None:
parts.append(f"新值: {new_value}")
if result_data.get("theme_changed") and result_data.get("new_theme"):
parts.append(f"主题已切换为: {result_data.get('new_theme')}")
message = result_data.get("message")
if message:
parts.append(str(message))
return "\n".join(parts)
config = result_data.get("data") or {}
if not isinstance(config, dict):
return result_data.get("message") or "个性化配置读取成功"
lines = ["当前个性化配置:"]
for key, value in config.items():
lines.append(f"- {key}: {value}")
message = result_data.get("message")
if message:
lines.append(str(message))
return "\n".join(lines)
def _summarize_todo_tasks(todo: Optional[Dict[str, Any]]) -> str:
if not isinstance(todo, dict):
return ""
@ -831,6 +869,7 @@ TOOL_FORMATTERS = {
"todo_create": _format_todo_create,
"todo_update_task": _format_todo_update_task,
"update_memory": _format_update_memory,
"manage_personalization": _format_manage_personalization,
"create_sub_agent": _format_create_sub_agent,
"wait_sub_agent": _format_wait_sub_agent,
"close_sub_agent": _format_close_sub_agent,