fix(personalization): 修复子智能体最大执行轮次保存丢失,多智能体豁免该上限
- sanitize_personalization_payload 白名单注册 sub_agent_max_turns / sub_agent_compress_threshold_tokens(此前保存时被静默丢弃,刷新回默认) - PUT /api/multiagent/settings 恢复默认由 pop() 改为写显式 null, 绕开 save 的 fallback=existing 复活旧值问题 - task.py:multi_agent_mode 任务一律不设轮次上限(含历史任务恢复), 该设置仅对传统后台子智能体生效 - 个人中心文案标明适用范围
This commit is contained in:
parent
ff927d6739
commit
34bb5d61cc
@ -2032,16 +2032,13 @@ class MainTerminalToolsExecutionMixin:
|
||||
task_message = build_master_dispatch_text(arguments.get("task", ""))
|
||||
summary_text = (arguments.get("summary") or f"{role.name}作业")[:80]
|
||||
thinking_mode = arguments.get("thinking_mode") or role.thinking_mode or "fast"
|
||||
# 读取子智能体压缩阈值与最大轮次配置
|
||||
# 读取子智能体压缩阈值配置(多智能体成员长期存在,不设轮次上限,
|
||||
# sub_agent_max_turns 仅对传统后台子智能体生效,这里不读取)
|
||||
_compress_threshold = 150_000
|
||||
_max_turns = None
|
||||
try:
|
||||
from modules.personalization_manager import load_personalization_config
|
||||
_prefs = load_personalization_config(data_dir) or {}
|
||||
_compress_threshold = int(_prefs.get("sub_agent_compress_threshold_tokens", 150_000))
|
||||
_raw_max_turns = _prefs.get("sub_agent_max_turns")
|
||||
if _raw_max_turns is not None:
|
||||
_max_turns = int(_raw_max_turns)
|
||||
except Exception:
|
||||
pass
|
||||
# 走原行 发事件创建(避免后期重建提供重复工能重费,直接使用 multi_agent_mode=True 调用)
|
||||
@ -2059,7 +2056,7 @@ class MainTerminalToolsExecutionMixin:
|
||||
system_prompt=system_prompt,
|
||||
task_message=task_message,
|
||||
compress_threshold_tokens=_compress_threshold,
|
||||
max_turns=_max_turns,
|
||||
max_turns=None, # 多智能体成员不设轮次上限(task.py 对 multi_agent_mode 亦强制豁免)
|
||||
)
|
||||
# 在多智能体模式下,子智能体是团队协作成员,不是传统后台任务。
|
||||
# run_in_background=False 避免触发后台完成通知轮询,保持主对话输入区可用。
|
||||
|
||||
@ -119,6 +119,9 @@ DEFAULT_PERSONALIZATION_CONFIG: Dict[str, Any] = {
|
||||
"goal_end_conditions": ["max_turns"], # 结束方式,可多选:max_turns / max_tokens
|
||||
"goal_max_turns": GOAL_MAX_TURNS_DEFAULT, # 最多自动续命轮数
|
||||
"goal_max_tokens": None, # 累计(输入+输出)token 上限;None 表示不启用
|
||||
# 传统模式子智能体设置(个人空间-子智能体管理;与多智能体无关)
|
||||
"sub_agent_compress_threshold_tokens": 150000, # 子智能体上下文压缩阈值,最小 10000
|
||||
"sub_agent_max_turns": None, # 子智能体最大执行轮次:None-默认 50 / 0-无上限 / 正整数-该值
|
||||
}
|
||||
|
||||
__all__ = [
|
||||
@ -630,9 +633,48 @@ def sanitize_personalization_payload(
|
||||
base.get("goal_max_tokens"), min_value=GOAL_MAX_TOKENS_MIN, max_value=GOAL_MAX_TOKENS_MAX
|
||||
)
|
||||
|
||||
# 传统模式子智能体:上下文压缩阈值(最小 10000,与 PUT /api/multiagent/settings 校验一致)
|
||||
if "sub_agent_compress_threshold_tokens" in data:
|
||||
base["sub_agent_compress_threshold_tokens"] = (
|
||||
_sanitize_optional_int(
|
||||
data.get("sub_agent_compress_threshold_tokens"),
|
||||
min_value=10000,
|
||||
max_value=10_000_000,
|
||||
)
|
||||
or 150000
|
||||
)
|
||||
else:
|
||||
base["sub_agent_compress_threshold_tokens"] = (
|
||||
_sanitize_optional_int(
|
||||
base.get("sub_agent_compress_threshold_tokens"),
|
||||
min_value=10000,
|
||||
max_value=10_000_000,
|
||||
)
|
||||
or 150000
|
||||
)
|
||||
|
||||
# 传统模式子智能体:最大执行轮次(None-默认 50 / 0-无上限 / 正整数-该值)
|
||||
if "sub_agent_max_turns" in data:
|
||||
base["sub_agent_max_turns"] = _sanitize_sub_agent_max_turns(data.get("sub_agent_max_turns"))
|
||||
else:
|
||||
base["sub_agent_max_turns"] = _sanitize_sub_agent_max_turns(base.get("sub_agent_max_turns"))
|
||||
|
||||
return base
|
||||
|
||||
|
||||
def _sanitize_sub_agent_max_turns(value: Any) -> Optional[int]:
|
||||
"""清洗子智能体最大轮次:None/''/非法值/负数 → None(未设置,下游默认 50);0 → 无上限;正整数 → 该值。"""
|
||||
if value is None or value == "" or isinstance(value, bool):
|
||||
return None
|
||||
try:
|
||||
parsed = int(value)
|
||||
except (TypeError, ValueError):
|
||||
return None
|
||||
if parsed < 0:
|
||||
return None
|
||||
return min(parsed, 100_000) # 防御性上限;需要更大时用 0 表示无上限
|
||||
|
||||
|
||||
def _sanitize_goal_end_conditions(value: Any) -> list:
|
||||
"""清洗目标模式结束方式列表,保证至少包含 max_turns。"""
|
||||
cleaned: list = []
|
||||
|
||||
@ -79,14 +79,18 @@ class SubAgentTask:
|
||||
# 上下文压缩配置
|
||||
# 默认阈值 150k tokens,可由外部覆盖(如个人空间子智能体管理配置)
|
||||
self.compress_threshold_tokens: int = int(task_record.get("compress_threshold_tokens") or 150_000)
|
||||
# 最大执行轮次(对应个人空间子智能体设置项 sub_agent_max_turns):
|
||||
# 最大执行轮次(对应个人空间子智能体设置项 sub_agent_max_turns,仅传统模式生效):
|
||||
# 未设置 → 默认 50;0(或负数)→ None 表示无上限;正整数 → 该值
|
||||
_raw_max_turns = task_record.get("max_turns")
|
||||
if _raw_max_turns is None:
|
||||
self.max_turns: Optional[int] = 50
|
||||
# 多智能体模式的子智能体是长期协作成员,一律无上限,不受该设置约束
|
||||
if multi_agent_mode:
|
||||
self.max_turns: Optional[int] = None
|
||||
else:
|
||||
_max_turns_int = int(_raw_max_turns)
|
||||
self.max_turns = _max_turns_int if _max_turns_int > 0 else None
|
||||
_raw_max_turns = task_record.get("max_turns")
|
||||
if _raw_max_turns is None:
|
||||
self.max_turns = 50
|
||||
else:
|
||||
_max_turns_int = int(_raw_max_turns)
|
||||
self.max_turns = _max_turns_int if _max_turns_int > 0 else None
|
||||
self.current_context_tokens: int = 0
|
||||
self._compress_round: int = 0
|
||||
|
||||
|
||||
@ -250,8 +250,11 @@ def update_multi_agent_settings_api():
|
||||
if "sub_agent_max_turns" in settings:
|
||||
max_turns_raw = settings.get("sub_agent_max_turns")
|
||||
if max_turns_raw is None:
|
||||
if prefs.pop("sub_agent_max_turns", None) is not None:
|
||||
# 置空恢复默认 50:写入显式 null(sanitize 会保留 None),不能 pop——
|
||||
# save_personalization_config 的 fallback=existing 会把已存在的旧值带回来
|
||||
if prefs.get("sub_agent_max_turns") is not None:
|
||||
dirty = True
|
||||
prefs["sub_agent_max_turns"] = None
|
||||
else:
|
||||
try:
|
||||
max_turns = int(max_turns_raw)
|
||||
|
||||
@ -1594,7 +1594,7 @@
|
||||
<span class="settings-row-copy">
|
||||
<span class="settings-row-title">最大执行轮次</span>
|
||||
<span class="settings-row-desc">
|
||||
子智能体单次任务的最大执行轮次(一轮 = 一次模型调用)。留空默认 50 轮;填 0 表示无上限(慎用,失控任务会持续消耗 API 额度)
|
||||
传统后台子智能体单次任务的最大执行轮次(一轮 = 一次模型调用)。留空默认 50 轮;填 0 表示无上限(慎用,失控任务会持续消耗 API 额度)。多智能体模式的团队成员是长期协作角色,不受此限制
|
||||
</span>
|
||||
</span>
|
||||
<div style="display: flex; gap: 6px; align-items: center">
|
||||
@ -2580,7 +2580,7 @@ watch(
|
||||
const subAgentRoles = ref<any[]>([]);
|
||||
const subAgentRolesLoading = ref(false);
|
||||
const subAgentCompressThreshold = ref(150000);
|
||||
/** 子智能体最大执行轮次:null/'' = 默认 50;0 = 无上限;正整数 = 该值 */
|
||||
/** 子智能体最大执行轮次(仅传统后台子智能体;多智能体成员不受限):null/'' = 默认 50;0 = 无上限;正整数 = 该值 */
|
||||
const subAgentMaxTurns = ref<number | null>(null);
|
||||
const subAgentSettingsSaving = ref(false);
|
||||
const subAgentModels = ref<any[]>([]);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user