feat: enhance persona tool management and update UI localization for subagent orchestration (#4990)

* feat: enhance persona tool management and update UI localization for subagent orchestration

* fix: remove debug logging for final ProviderRequest in build_main_agent function
This commit is contained in:
Soulter
2026-02-09 22:38:05 +08:00
committed by GitHub
parent 7193454d50
commit da4bb6549c
5 changed files with 32 additions and 45 deletions
+27 -30
View File
@@ -326,6 +326,24 @@ async def _ensure_persona_and_skills(
)
tmgr = plugin_context.get_llm_tool_manager()
# inject toolset in the persona
if (persona and persona.get("tools") is None) or not persona:
persona_toolset = tmgr.get_full_tool_set()
for tool in list(persona_toolset):
if not tool.active:
persona_toolset.remove_tool(tool.name)
else:
persona_toolset = ToolSet()
if persona["tools"]:
for tool_name in persona["tools"]:
tool = tmgr.get_func(tool_name)
if tool and tool.active:
persona_toolset.add_tool(tool)
if not req.func_tool:
req.func_tool = persona_toolset
else:
req.func_tool.merge(persona_toolset)
# sub agents integration
orch_cfg = plugin_context.get_config().get("subagent_orchestrator", {})
so = plugin_context.subagent_orchestrator
@@ -371,22 +389,19 @@ async def _ensure_persona_and_skills(
assigned_tools.add(name)
if req.func_tool is None:
toolset = ToolSet()
else:
toolset = req.func_tool
req.func_tool = ToolSet()
# add subagent handoff tools
for tool in so.handoffs:
toolset.add_tool(tool)
req.func_tool.add_tool(tool)
# check duplicates
if remove_dup:
names = toolset.names()
handoff_names = {tool.name for tool in so.handoffs}
for tool_name in assigned_tools:
if tool_name in names:
toolset.remove_tool(tool_name)
req.func_tool = toolset
if tool_name in handoff_names:
continue
req.func_tool.remove_tool(tool_name)
router_prompt = (
plugin_context.get_config()
@@ -395,32 +410,14 @@ async def _ensure_persona_and_skills(
).strip()
if router_prompt:
req.system_prompt += f"\n{router_prompt}\n"
return
# inject toolset in the persona
if (persona and persona.get("tools") is None) or not persona:
toolset = tmgr.get_full_tool_set()
for tool in list(toolset):
if not tool.active:
toolset.remove_tool(tool.name)
else:
toolset = ToolSet()
if persona["tools"]:
for tool_name in persona["tools"]:
tool = tmgr.get_func(tool_name)
if tool and tool.active:
toolset.add_tool(tool)
if not req.func_tool:
req.func_tool = toolset
else:
req.func_tool.merge(toolset)
try:
event.trace.record(
"sel_persona", persona_id=persona_id, persona_toolset=toolset.names()
"sel_persona",
persona_id=persona_id,
persona_toolset=persona_toolset.names(),
)
except Exception:
pass
logger.debug("Tool set for persona %s: %s", persona_id, toolset.names())
async def _request_img_caption(
+3 -2
View File
@@ -129,8 +129,9 @@ DEFAULT_CONFIG = {
},
# SubAgent orchestrator mode:
# - main_enable = False: disabled; main LLM mounts tools normally (persona selection).
# - main_enable = True: enabled; main LLM will include handoff tools and can optionally
# remove tools that are duplicated on subagents via remove_main_duplicate_tools.
# - main_enable = True: enabled; main LLM keeps its own tools and includes handoff
# tools (transfer_to_*). remove_main_duplicate_tools can remove tools that are
# duplicated on subagents from the main LLM toolset.
"subagent_orchestrator": {
"main_enable": False,
"remove_main_duplicate_tools": False,
@@ -2,7 +2,7 @@
"page": {
"title": "SubAgent Orchestration",
"beta": "Experimental",
"subtitle": "The main LLM only chats and delegates; tools live on individual SubAgents."
"subtitle": "The main LLM can use its own tools directly and delegate tasks to SubAgents via handoff."
},
"actions": {
"refresh": "Refresh",
@@ -2,7 +2,7 @@
"page": {
"title": "SubAgent 编排",
"beta": "实验性",
"subtitle": "主 LLM 只负责聊天与分派(handoff),工具挂载在各个 SubAgent。"
"subtitle": "主 LLM 可直接使用自身工具,也可通过 handoff 分派给各个 SubAgent。"
},
"actions": {
"refresh": "刷新",
-11
View File
@@ -142,17 +142,6 @@
</v-col>
</v-row>
<div class="mt-3">
<div class="text-caption text-medium-emphasis">{{ tm('cards.previewTitle') }}</div>
<div class="d-flex align-center" style="gap: 8px; flex-wrap: wrap;">
<v-chip size="small" variant="outlined" color="primary">
{{ tm('cards.transferPrefix', { name: agent.name || '...' }) }}
</v-chip>
<v-chip size="small" variant="tonal" color="secondary" v-if="agent.persona_id">
{{ tm('cards.personaChip', { id: agent.persona_id }) }}
</v-chip>
</div>
</div>
</v-expansion-panel-text>
</v-expansion-panel>
</v-expansion-panels>