fix(marketplace): address code review findings
- Fix str.format() crash when user input contains curly braces - Fix Layer 2 passing str to find_best_agent (expects list[str]) - Fix AlignmentGuard fail-open on LLM audit failure (now fail-closed) - Fix _config_reload_lock not initialized in create_app() - Fix evolve_soul redundant reflector.reflect() call (reuse existing reflection) - Fix test mocks using AsyncMock for sync find_best_agent method - Remove unused _COMPLEXITY_CLASSIFY_PROMPT constant
This commit is contained in:
parent
8713636d50
commit
bba394be38
|
|
@ -186,16 +186,6 @@ _CHAT_MODE_RE = re.compile(
|
||||||
re.IGNORECASE,
|
re.IGNORECASE,
|
||||||
)
|
)
|
||||||
|
|
||||||
_COMPLEXITY_CLASSIFY_PROMPT = (
|
|
||||||
"Assess the complexity of the following user request on a scale of 0.0 to 1.0.\n"
|
|
||||||
"0.0 = trivial greeting / simple chat\n"
|
|
||||||
"0.3 = single-skill task (e.g. search, translate)\n"
|
|
||||||
"0.7 = multi-step or cross-domain task (e.g. market research + competitor analysis)\n"
|
|
||||||
"1.0 = highly complex, multi-agent collaboration needed\n\n"
|
|
||||||
'User request: "{content}"\n\n'
|
|
||||||
'Respond ONLY with a JSON object: {{"complexity": <float>}}'
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class CostAwareRouter:
|
class CostAwareRouter:
|
||||||
"""三层成本感知路由器。
|
"""三层成本感知路由器。
|
||||||
|
|
@ -251,7 +241,13 @@ class CostAwareRouter:
|
||||||
if self._llm_gateway is None:
|
if self._llm_gateway is None:
|
||||||
return 0.5
|
return 0.5
|
||||||
|
|
||||||
prompt = _COMPLEXITY_CLASSIFY_PROMPT.format(content=content)
|
prompt = (
|
||||||
|
'You are a complexity classifier. Rate the complexity of the user request on a scale of 0.0 to 1.0.\n'
|
||||||
|
'0.0 = trivial greeting, 0.3 = simple question, 0.5 = moderate task, '
|
||||||
|
'0.7 = complex multi-step task, 1.0 = very complex research task.\n\n'
|
||||||
|
f'User request: "{content}"\n\n'
|
||||||
|
'Respond ONLY with a JSON object: {"complexity": <float>}'
|
||||||
|
)
|
||||||
try:
|
try:
|
||||||
response = await self._llm_gateway.chat(
|
response = await self._llm_gateway.chat(
|
||||||
messages=[{"role": "user", "content": prompt}],
|
messages=[{"role": "user", "content": prompt}],
|
||||||
|
|
@ -283,7 +279,10 @@ class CostAwareRouter:
|
||||||
"""Layer 2: 高复杂度任务通过 org_context.find_best_agent 路由。"""
|
"""Layer 2: 高复杂度任务通过 org_context.find_best_agent 路由。"""
|
||||||
if self._org_context is not None and hasattr(self._org_context, "find_best_agent"):
|
if self._org_context is not None and hasattr(self._org_context, "find_best_agent"):
|
||||||
try:
|
try:
|
||||||
best_agent = await self._org_context.find_best_agent(content)
|
# Extract capability-like keywords from content for matching
|
||||||
|
# find_best_agent expects list[str] of required capabilities
|
||||||
|
content_words = [w for w in content.split() if len(w) > 2][:5]
|
||||||
|
best_agent = self._org_context.find_best_agent(required_capabilities=content_words)
|
||||||
if best_agent is not None:
|
if best_agent is not None:
|
||||||
agent_name = best_agent if isinstance(best_agent, str) else getattr(best_agent, "name", str(best_agent))
|
agent_name = best_agent if isinstance(best_agent, str) else getattr(best_agent, "name", str(best_agent))
|
||||||
result = SkillRoutingResult(
|
result = SkillRoutingResult(
|
||||||
|
|
|
||||||
|
|
@ -149,7 +149,7 @@ class EvolutionMixin:
|
||||||
|
|
||||||
# Step 2: Soul 进化检查
|
# Step 2: Soul 进化检查
|
||||||
if memory_store is not None:
|
if memory_store is not None:
|
||||||
await self.evolve_soul(task, result, memory_store)
|
await self.evolve_soul(task, result, memory_store, reflection=reflection)
|
||||||
|
|
||||||
# Step 3: 如果有改进建议,触发 Prompt 优化
|
# Step 3: 如果有改进建议,触发 Prompt 优化
|
||||||
if not reflection.suggestions:
|
if not reflection.suggestions:
|
||||||
|
|
@ -378,6 +378,7 @@ class EvolutionMixin:
|
||||||
task: TaskMessage,
|
task: TaskMessage,
|
||||||
result: TaskResult,
|
result: TaskResult,
|
||||||
memory_store: MemoryStore | None = None,
|
memory_store: MemoryStore | None = None,
|
||||||
|
reflection: Reflection | None = None,
|
||||||
) -> bool:
|
) -> bool:
|
||||||
"""Check if soul should be updated based on accumulated reflections.
|
"""Check if soul should be updated based on accumulated reflections.
|
||||||
|
|
||||||
|
|
@ -389,10 +390,10 @@ class EvolutionMixin:
|
||||||
if memory_store is None:
|
if memory_store is None:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if self._reflector is None:
|
if reflection is None:
|
||||||
return False
|
if self._reflector is None:
|
||||||
|
return False
|
||||||
reflection = await self._reflector.reflect(task, result)
|
reflection = await self._reflector.reflect(task, result)
|
||||||
|
|
||||||
# 只关注低质量且有建议的反思
|
# 只关注低质量且有建议的反思
|
||||||
if reflection.quality_score >= 0.5:
|
if reflection.quality_score >= 0.5:
|
||||||
|
|
|
||||||
|
|
@ -159,7 +159,11 @@ class AlignmentGuard:
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"LLM audit failed: {e}")
|
logger.warning(f"LLM audit failed: {e}")
|
||||||
return AlignmentCheckResult(passed=True, checked_by="rule")
|
return AlignmentCheckResult(
|
||||||
|
passed=False,
|
||||||
|
violations=[f"LLM audit unavailable: {e}"],
|
||||||
|
checked_by="rule",
|
||||||
|
)
|
||||||
|
|
||||||
def record_interaction(self, session_id: str) -> CascadeAlert | None:
|
def record_interaction(self, session_id: str) -> CascadeAlert | None:
|
||||||
"""记录一次 agent 间交互,超过阈值返回 CascadeAlert"""
|
"""记录一次 agent 间交互,超过阈值返回 CascadeAlert"""
|
||||||
|
|
|
||||||
|
|
@ -487,6 +487,7 @@ def create_app(
|
||||||
app.state.runner = BackgroundRunner(task_store=app.state.task_store)
|
app.state.runner = BackgroundRunner(task_store=app.state.task_store)
|
||||||
app.state.server_config = server_config
|
app.state.server_config = server_config
|
||||||
app.state.api_key = effective_api_key
|
app.state.api_key = effective_api_key
|
||||||
|
app.state._config_reload_lock = asyncio.Lock()
|
||||||
|
|
||||||
# Initialize session manager for Chat mode
|
# Initialize session manager for Chat mode
|
||||||
from agentkit.session.manager import SessionManager
|
from agentkit.session.manager import SessionManager
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,7 @@ class TestCapabilityMatching:
|
||||||
))
|
))
|
||||||
|
|
||||||
# Mock find_best_agent to return the research agent
|
# Mock find_best_agent to return the research agent
|
||||||
org_context.find_best_agent = AsyncMock(
|
org_context.find_best_agent = MagicMock(
|
||||||
return_value=org_context.get_agent_profile("research_agent")
|
return_value=org_context.get_agent_profile("research_agent")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -515,7 +515,7 @@ class TestFullPipeline:
|
||||||
skills=["market_analysis"],
|
skills=["market_analysis"],
|
||||||
current_load=0,
|
current_load=0,
|
||||||
))
|
))
|
||||||
org_context.find_best_agent = AsyncMock(
|
org_context.find_best_agent = MagicMock(
|
||||||
return_value=org_context.get_agent_profile("analyst")
|
return_value=org_context.get_agent_profile("analyst")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -267,7 +267,7 @@ class TestLayer2CapabilityMatching:
|
||||||
"""'做市场调研+竞品分析' 复杂度 > 0.7,触发能力匹配"""
|
"""'做市场调研+竞品分析' 复杂度 > 0.7,触发能力匹配"""
|
||||||
gateway = _make_llm_gateway(json.dumps({"complexity": 0.85}))
|
gateway = _make_llm_gateway(json.dumps({"complexity": 0.85}))
|
||||||
org_context = MagicMock()
|
org_context = MagicMock()
|
||||||
org_context.find_best_agent = AsyncMock(return_value="market-researcher")
|
org_context.find_best_agent = MagicMock(return_value="market-researcher")
|
||||||
|
|
||||||
router = CostAwareRouter(llm_gateway=gateway, model="default", org_context=org_context)
|
router = CostAwareRouter(llm_gateway=gateway, model="default", org_context=org_context)
|
||||||
result = await router.route(
|
result = await router.route(
|
||||||
|
|
@ -289,7 +289,7 @@ class TestLayer2CapabilityMatching:
|
||||||
agent_obj = MagicMock()
|
agent_obj = MagicMock()
|
||||||
agent_obj.name = "analyst-agent"
|
agent_obj.name = "analyst-agent"
|
||||||
org_context = MagicMock()
|
org_context = MagicMock()
|
||||||
org_context.find_best_agent = AsyncMock(return_value=agent_obj)
|
org_context.find_best_agent = MagicMock(return_value=agent_obj)
|
||||||
|
|
||||||
router = CostAwareRouter(llm_gateway=gateway, model="default", org_context=org_context)
|
router = CostAwareRouter(llm_gateway=gateway, model="default", org_context=org_context)
|
||||||
result = await router.route(
|
result = await router.route(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue