Skip to content

Commit 3dd29a7

Browse files
committed
feat: 重构角色管理面板,优化加载速度
1 parent bac2176 commit 3dd29a7

14 files changed

Lines changed: 1511 additions & 70 deletions

File tree

.claude/skills/SKILL.md

Lines changed: 511 additions & 0 deletions
Large diffs are not rendered by default.

.claude/skills/godot-tscn-format/SKILL.md

Lines changed: 511 additions & 0 deletions
Large diffs are not rendered by default.

addons/agent/agent.gd

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,10 @@ class GlobalSetting:
131131
# 初始化角色管理器
132132
role_manager = AgentRoleConfig.RoleManager.new(roles_file)
133133

134-
# 如果没有角色,添加默认角色(需要 await 等待工具列表加载)
134+
# 如果没有角色,等待一帧确保工具列表就绪后创建默认角色
135135
if role_manager.roles.is_empty():
136-
await role_manager.add_default_roles()
136+
await AlphaAgentPlugin.wait_for_scene_tree_frame()
137+
role_manager.add_default_roles()
137138

138139
# 初始化技能管理器
139140
skill_manager = AgentSkillConfig.SkillManager.new(skill_directory)

addons/agent/scripts/role_config.gd

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -127,26 +127,18 @@ class RoleManager:
127127
AlphaAgentPlugin.print_alpha_message("{0}个角色加载完成".format([roles.size()]))
128128

129129
func add_default_roles():
130-
# 使用单例,等待 main_panel 初始化
130+
# 用户手动触发,此时 main_panel 必定已就绪
131131
var singleton = AlphaAgentSingleton.get_instance()
132+
if singleton.main_panel == null:
133+
push_error("主面板未初始化,无法创建默认角色")
134+
return
132135

133-
# 等待 main_panel 初始化(在 _enter_tree 中创建)
134-
var max_wait_time = 10.0
135-
var elapsed_time = 0.0
136-
var start_time = Time.get_ticks_msec()
137-
138-
while singleton.main_panel == null:
139-
await AlphaAgentPlugin.wait_for_scene_tree_frame()
140-
elapsed_time = (Time.get_ticks_msec() - start_time) / 1000.0
141-
if elapsed_time >= max_wait_time:
142-
push_error("等待 main_panel 初始化超时")
143-
return
144-
145-
# 等待一帧,确保工具列表已加载
146-
await AlphaAgentPlugin.wait_for_scene_tree_frame()
136+
var tools_node = singleton.main_panel.get("tools")
137+
if tools_node == null or not (tools_node is AgentTools):
138+
push_error("工具列表未初始化,无法创建默认角色")
139+
return
147140

148-
# 缓存工具列表,避免重复调用
149-
var tools_dict = singleton.main_panel.tools.get_function_name_list()
141+
var tools_dict = tools_node.get_function_name_list()
150142
var tools_keys = tools_dict.keys()
151143

152144
# 添加默认角色
@@ -177,7 +169,6 @@ class RoleManager:
177169

178170
AlphaAgentPlugin.print_alpha_message("{0}个默认角色创建完成".format([roles.size()]))
179171

180-
181172
func save_datas():
182173
var data = {
183174
"current_role_id": current_role_id,

addons/agent/ui/chat/input_container.gd

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ var menu_list_type: MenuListType = MenuListType.None
3838
var _cached_file_list: Array = [] # 文件列表缓存
3939
var _cached_file_list_valid: bool = false # 缓存是否有效
4040

41+
var _clamp_scheduled: bool = false # 延迟合并高度重算
42+
var _last_menu_search: String = "" # 上次菜单搜索词,避免重复过滤
43+
4144
var command_list = [
4245
{
4346
"command": "/memory",
@@ -412,7 +415,23 @@ func check_disallowed_char(text: String) -> bool:
412415

413416
func on_user_input_text_changed():
414417
var text = user_input.text
415-
_clamp_input_height()
418+
_schedule_clamp()
419+
420+
# 提取搜索前缀,避免每次按键都重新过滤
421+
var search_prefix = ""
422+
if "@" in text:
423+
var at_idx = text.rfind("@")
424+
var space_after_at = text.find(" ", at_idx)
425+
if space_after_at < 0:
426+
space_after_at = text.length()
427+
search_prefix = text.substr(at_idx, space_after_at - at_idx)
428+
elif text.begins_with("/") and check_disallowed_char(text):
429+
search_prefix = text
430+
431+
# 搜索词未变则跳过,减少不必要的 UI 刷新
432+
if search_prefix == _last_menu_search:
433+
return
434+
_last_menu_search = search_prefix
416435

417436
# 检测 @ 触发文件列表
418437
if "@" in text:
@@ -464,9 +483,14 @@ func on_user_input_text_changed():
464483
menu_list_type = MenuListType.None
465484
input_menu_list.hide()
466485
input_menu_list.clear()
467-
468486
## 限制输入框最大高度,超出后内部滚动
469-
func _clamp_input_height():
487+
func _schedule_clamp():
488+
if not _clamp_scheduled:
489+
_clamp_scheduled = true
490+
call_deferred("_do_clamp_input_height")
491+
492+
func _do_clamp_input_height():
493+
_clamp_scheduled = false
470494
const MAX_HEIGHT := 200.0
471495
const MIN_HEIGHT := 60.0
472496

addons/agent/ui/chat/message_item.gd

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ func _ready() -> void:
6464
expand_button.button_pressed = auto_expand_think
6565
set_expand_icon_flip(auto_expand_think)
6666
think_content_panel.visible = auto_expand_think
67+
set_process(false)
6768

6869
func _process(delta: float) -> void:
6970
if thinking:
@@ -77,6 +78,8 @@ func update_think_content(text: String, start_timer: bool = true):
7778
return
7879

7980
thinking = start_timer
81+
if start_timer and show_think:
82+
set_process(true)
8083
think_container.show()
8184
# 去除首尾空白和换行,避免RichTextLabel渲染出过大高度
8285
think_content.text = text.strip_edges()
@@ -86,6 +89,7 @@ func update_think_content(text: String, start_timer: bool = true):
8689
func update_message_content(text: String):
8790
message_type = MessageType.AssistantMessage
8891
thinking = false
92+
set_process(false)
8993
if show_think:
9094
thinking_label.text = "思考了"
9195
# 去除首尾空白和换行,避免RichTextLabel渲染出过大高度
@@ -122,6 +126,7 @@ func used_tools(tool_calls: Array):
122126
message_type = MessageType.ToolMessage
123127
wait_using_tool.hide()
124128
thinking = false
129+
set_process(false)
125130
for tool in tool_calls:
126131
var use_tool_item = USE_TOOL_ITEM.instantiate()
127132
use_tool_container.add_child(use_tool_item)
@@ -149,6 +154,7 @@ func on_click_rich_text_url(meta):
149154
func update_error_message(error_content: String, detail):
150155
message_type = MessageType.ErrorMessage
151156
thinking = false
157+
set_process(false)
152158
use_tool_container.hide()
153159
wait_using_tool.hide()
154160
think_content_panel.hide()
@@ -164,6 +170,8 @@ func update_finished_message(type: String):
164170
if type == "Stop":
165171
stop_message.show()
166172
thinking = false
173+
set_process(false)
167174
elif type == "Success":
168175
success_message.show()
169176
thinking = false
177+
set_process(false)

addons/agent/ui/memory/memory_container.gd

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,17 @@ extends VBoxContainer
1313
const MEMORY_ITEM = preload("uid://cr2sav6by4tal")
1414
const CONFIG = preload("uid://b4bcww0bmnxt0")
1515

16+
var _initialized: bool = false
1617
func _ready() -> void:
17-
load_from_project()
1818
visibility_changed.connect(on_visibility_changed)
1919
add_global_memory.pressed.connect(on_add_global_memory)
2020
add_project_memory.pressed.connect(on_add_project_memory)
2121

2222
func on_visibility_changed():
2323
if visible:
24+
if not _initialized:
25+
_initialized = true
26+
load_from_project()
2427
clear_memory_nodes()
2528
add_memory_nodes()
2629
else:

addons/agent/ui/role/edit_function_item.gd

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,8 @@ func set_active(_active: bool):
3131
active_icon.visible = active
3232
disactive_icon.visible = not active
3333

34+
func set_disabled(disabled: bool):
35+
fucntion_active_button.disabled = disabled
36+
3437
func on_click_function_active_button():
3538
set_active(not active)

0 commit comments

Comments
 (0)